在运行某些测试时,我需要运行一系列命令。如果有办法完成所有这些操作,那对我来说将非常有用,并且可以节省大量时间:
- 运行我需要运行的命令
- 将命令的所有输出重定向到指定文件
- 将原始命令包含在指定文件中
- 在终端中打印原始命令的输出
人们建议我使用 tee,它可以很好地打印到终端以及发送到文件,但不包含原始命令。我希望最终得到的是一个文件,其中第一行是我运行的命令,然后下面是命令的输出。
有人建议这样:
echo "ls -l" | xargs -I{} bash -c "echo >> output.file; eval {} >> output.file"
但这既不会在终端中打印输出,也不会在文件中包含原始命令。
我将非常感激任何想法。
答案1
这就是tee
您正在寻找的。
ls -l | tee outfile
将的输出打印ls -l
到stdout(即终端)并outfile
同时保存在文件中。但:它不会将命令名称写入 stdout 或文件。要实现这一点,只需echo
在运行命令之前输入命令名称,然后将两个输出都通过管道传输到tee
:
( echo "ls -l" && ls -l ) | tee outfile
输入起来很麻烦,那么为什么不定义一个函数呢?
both(){ ( echo "$@" && "$@" ) | tee outfile ;}
之后你就可以运行
both ls -l
以获得所需的结果。将该函数放入您的程序中,~/.bashrc
以便在每个新终端中定义它。
如果您希望能够将输出文件指定为第一个参数,如
both output ls -l
改为:
both(){ ( echo "${@:2}" && "${@:2}" ) | tee "$1" ;}
如果您不想覆盖输出文件而是希望将输出文件附加到其中,请将选项添加-a
到tee
。
答案2
你可以使用这个script
命令,它会将终端上打印的所有内容制作成一个 Typescript 文件。它会创建一个分叉的 shell,并记录所有内容,直到退出该 shell。
$ script my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
Script done on Tue 28 Nov 2017 09:46:27 AM UTC
然后如果我cat my_output
得到相同的输出:
$ cat my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
exit
Script done on Tue 28 Nov 2017 09:46:27 AM UTC
答案3
您可以将 shell 的调试功能与以下功能一起使用tee
:
( set -x; command1 args...; command2 args ) 2>&1 | tee output.log
( ... )
启动一个子 shell,它允许您“收集”在子 shell 中执行的所有命令的输出流。它还包含set
以下命令对此子 shell 的影响。set -x
启用x
shell 选项,该选项在运行 shell 运行的所有命令之前将其打印到标准错误流中。2>&1
将流 2 (标准错误) 重定向到流 1 (标准输出)。|
将左侧命令的标准输出流重定向到右侧命令的标准输入流。tee FILE
将标准输入流复制到文件FILE
和标准输出。
如果您的命令序列已经在脚本文件中,那么像这样运行它会更有意义:
bash -x /path/to/script args... 2>&1 | tee output.log