自定义Bash脚本记录终端输入输出及提示符问题求助
自定义Bash脚本记录终端操作及提示符的问题
我正在学习Bash,想写一个脚本记录终端的所有操作(类似script命令功能),但不想使用script命令。最初编写的脚本如下:
rm file; tee -a file | bash 2>&1 | tee -a file
这个脚本可以正常工作,但我希望同时记录Bash的默认提示符。于是我查了man bash,加上-i选项修改了脚本(这里必须用rm和tee -a而非仅tee,否则会产生错位输出,所以选了这种简单方式):
rm file; tee -a file | bash -i 2>&1 | tee -a file
但修改后的脚本无法正常工作!它仅执行并保存一条命令。请问该如何解决,以及问题产生的原因是什么?
原脚本执行后,cat file的输出示例:
echo 1 1 echo 2 2
期望的输出:
user@host:~$ echo 1 1 user@host:~$ echo 2 2
问题原因及解决方法
问题原因
当用bash -i启动交互式Shell时,它会默认直接从终端(/dev/tty)读取输入,而非从管道中获取tee传来的内容。这就导致tee的输入管道被忽略,交互式Shell只接收一次终端输入,执行后就处于等待状态,因此只能记录一条命令。
同时,bash -i的输出(包括提示符)虽会被第二个tee写入文件,但由于输入来源切换到终端,管道的数据流被打断,后续操作无法被第一个tee捕获,也就无法完整记录到文件中。
解决方法
要让交互式Bash从管道读取输入,同时保留提示符,可以借助命名管道协调输入输出,强制交互式Bash从标准输入读取而非终端。以下是可行的脚本:
rm -f file logpipe mkfifo logpipe # 后台启动tee,从命名管道读取内容并写入file,同时传递输入给bash tee -a file < logpipe & # 启动交互式bash,合并标准输出与错误后写入file,再将内容传入命名管道 bash -i 2>&1 | tee -a file > logpipe # 清理命名管道 rm -f logpipe
脚本说明
mkfifo logpipe创建命名管道,用来循环传递输入输出,避免管道数据流中断。tee -a file < logpipe &:让tee从命名管道读取内容并写入file,后台运行等待输入。bash -i 2>&1 | tee -a file > logpipe:启动交互式Bash,合并其标准输出和错误,用tee写入file后再将内容传入命名管道,这样既捕获了输入命令,也记录了Bash的提示符。- 最后清理临时创建的命名管道。
执行该脚本后,cat file就能得到包含提示符的完整操作记录,与期望输出一致。
内容的提问来源于stack exchange,提问作者dr.harm
相关产品推荐
相关产品推荐

