今天写了一个简单的脚本,把history重定向/opt/log/history中,并以日期的格式输出
#!/bin/bash
export HISTSIZE=1000000
export HISTFILESIZE=1000000000
export HISTTIMEFORMAT="%F %T `whoami` "
his_date=`date +%Y-%m-%d`
his=`history |wc -l`
if [ $his -ge 0 ]; then
     history -a
    history 1> /opt/log/history/$his_date
    history -c
    echo "xxx"
fi
 
到/opt/log/history/目录中确实多了一个以时间格式的文件,打开文件发现里边是空的。
为什么文件是空的?确实这个脚本是没有问题的,并可以执行
问题出在哪里?结果发现问题是history这条命令,我们执行
#which history
/usr/bin/which: no history in (/usr/lib/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)
#whatis history
history              (3)  - GNU History Library
history [builtins]   (1)  - bash built-in commands, see bash(1)
原来history是系统内建命令
 
了解一下什么是内建命令
内建命令指的就是包含在Bash工具包中的 命令, 从字面意思上看就是 built in. 这主要是考虑到执行效率的问题 -- 内建命令将比外部命令执行的更快, 一部分原因是因为外部命令通常都需要fork出一个单独的进程来执行 -- 另一部分原因是特定的内建命令需要直接访问shell的内核部分.
当一个命令或者是shell本身需要初始化(或者 创建)一个新的子进程来执行一个任务的时候, 这种行为被称为 fork. 这个新产生的进程被叫做 子进程, 并且这个进程是从 父进程fork出来的. 当 子进程执行它的任务时, 父进程也在运行.
注意: 当 父进程获得了 子进程进程ID时, 父进程可以给子进程传递参数, 然而 反过来却不行
通常情况下, 脚本中的Bash 内建命令在运行的时候是不会fork出一个子进程的. 但是脚本中的外部或者过滤命令通常 fork出一个子进程.
 
如何解决问题
去掉脚本中的 #!/bin/bash, 问题解决