在运行一些测试时,我需要运行一系列命令。如果有办法做所有这些事情,这对我来说非常有用,并为我节省了很多时间:
人们建议我使用 tee,它可以很好地打印到终端以及发送到文件,但不包含原始命令。我想要结束的是一个文件,其中第一行是我运行的命令,然后是命令的输出。
有人建议这样做:
echo "ls -l" | xargs -I{} bash -c "echo >> output.file; eval {} >> output.file"
Run Code Online (Sandbox Code Playgroud)
但这既不会在终端中打印输出,也不会在文件中包含原始命令。
我很感激任何想法。
des*_*ert 14
这就是tee
你要找的。
ls -l | tee outfile
Run Code Online (Sandbox Code Playgroud)
将输出打印ls -l
到标准输出(即终端)并同时保存在文件outfile
中。但是:它既不会将命令名称写入 stdout,也不会写入文件。要实现这一点,只需echo
在运行命令之前输入命令名称并将两个输出通过管道传输到tee
:
( echo "ls -l" && ls -l ) | tee outfile
Run Code Online (Sandbox Code Playgroud)
打字很麻烦,为什么不定义一个函数呢?
both(){ ( echo "$@" && "$@" ) | tee outfile ;}
Run Code Online (Sandbox Code Playgroud)
之后你可以运行
both ls -l
Run Code Online (Sandbox Code Playgroud)
以获得所需的结果。将函数放入您的~/.bashrc
每个新终端中以定义它。
如果您希望能够将输出文件指定为第一个参数,如
both output ls -l
Run Code Online (Sandbox Code Playgroud)
改为:
both(){ ( echo "${@:2}" && "${@:2}" ) | tee "$1" ;}
Run Code Online (Sandbox Code Playgroud)
如果您不希望输出文件被覆盖而是附加到它,请将-a
选项添加到tee
.
您可以使用该script
命令来制作打印到终端的所有内容的打字稿文件。它创建一个分叉的 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
Run Code Online (Sandbox Code Playgroud)
然后,如果我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
Run Code Online (Sandbox Code Playgroud)
您可以将 shell 的调试功能与tee
:
( set -x; command1 args...; command2 args ) 2>&1 | tee output.log
Run Code Online (Sandbox Code Playgroud)
( ... )
启动一个子 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
Run Code Online (Sandbox Code Playgroud)