将每个命令的输出保存到单独的日志文件中?

将每个命令的输出保存到单独的日志文件中?

我想将tee每个交互式执行的命令输出到一系列单独的日志文件,每个命令一个。为此,我编写了以下脚本,该脚本将设置为 shell 启动时最后运行的脚本(结束.bashrc):

date=$(date +%Y-%m-%d_%H-%M-%S)
randstr=$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 4)
dir=~/log/"${date}_${randstr}"
mkdir "$dir"
i=0
while :
do
    read -e -p "user@host:$(pwd)\$ " cmd
    eval "$cmd 2>&1 | tee \"${dir}/${i}-${cmd}\"" 
    (( i++ ))
done

然而,这也存在一些问题。首先,一旦遇到换行符,它就会停止读取,因为这就是read工作原理。我不想要这种行为。我希望它的行为与 shell 完全相同,因此,例如,当我编写ls &&并按下时Return,它会在执行任何操作之前等待更多输入。

我怎样才能实现这个目标?通过 shell 脚本实现这一点是否可能/可行?我应该使用更传统的编程语言吗?我是否应该打补丁bash来实现这一目标?

答案1

# teeshell

date=$(date +%Y-%m-%d_%H-%M-%S)
randstr=$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 4)
dir="$(echo ~/log/"${date}_${randstr}")"
mkdir "$dir"
# Redirect everything to tee and perl
exec 1> >(tee /dev/tty |
          perl -pe '                                                                          
            sub reopen {
              open(OUT,">'$dir'/".++$i);
              select OUT;
              $| = 1;
            }                     
            BEGIN {
              `echo $$ > "'$dir'"/pid`;
              reopen();                                       
              $SIG{HUP} = \&reopen;                                                           
            }') 2>&1

# wait for perl to save the pid
while [ ! -f "$dir"/pid ] ; do
    true
done

# Magic! Make perl save to a new file with a kill -HUP
PS1="[\$(kill -HUP `cat "$dir"/pid`)][\u@\h:\w]\$ "

跑步:

. teeshell

相关内容