从命令直接输出到包含原始命令的文件,并在终端中打印


8

运行一些测试时,我需要运行一系列命令。如果有一种方法可以完成所有这些事情,那对我来说将非常有用,并且可以节省很多时间:

  • 运行我需要运行的命令
  • 将命令的所有输出重定向到指定文件
  • 将原始命令包括在指定文件中
  • 在终端中打印原始命令的输出

人们向我建议使用tee,它在打印到终端以及发送到文件方面做得很好,但不包含原始命令。我要结束的是一个文件,其中第一行是我运行的命令,然后在其下是该命令的输出。

有人建议这样做:

echo "ls -l" | xargs -I{} bash -c "echo >> output.file; eval {} >> output.file"

但这不会在终端中输出输出,也不会在文件中包含原始命令。

我将不胜感激。



我在搜索中没有找到这个-并不完全相同,但是可能会导致我找到答案。
shaneoh

是的,这就是为什么我说几乎是重复的。但是,老实说,您可以从那里获取几乎所有解决方案,并通过管道将其使用tee
Sergiy Kolodyazhnyy

Answers:


14

那就是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


9

您可以使用该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

然后,如果我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

6

您可以结合使用shell的调试功能tee

( set -x; command1 args...; command2 args ) 2>&1 | tee output.log
  • ( ... )启动一个子shell,它使您可以“收集”在该子shell中执行的所有命令的输出流。它还包含set此子外壳下面命令的效果。

  • set -x启用xshell选项,该选项在运行外壳程序之前将其运行的所有命令打印到标准错误流。

  • 2>&1 将流2(标准错误)重定向到流1(标准输出)。

  • | 将左命令的标准输出流重定向到右命令的标准输入流。

  • tee FILE将标准输入流复制到文件FILE和标准输出。

如果您的命令序列已经在脚本文件中,则按如下方式运行它会更有意义:

bash -x /path/to/script args... 2>&1 | tee output.log
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.