从交互式 shell 回显命令并输出到文件

从交互式 shell 回显命令并输出到文件

我正在寻找一种优雅的方式让 bash 写入我执行的命令,然后从交互式提示符将该命令的输出写入文件。运行这样的命令:

$ls -alh > list_dir

会向 list_dir 写入类似以下内容:

$ls -alh > list_dir
total 12K
drwxr-xr-x 2 root root 4.0K Dec 21 13:30 .
drwx------ 5 root root 4.0K Dec 21 13:30 ..
-rw-r--r-- 1 root root  842 Dec 21 13:09 file
-rw-r--r-- 1 root root    0 Dec 21 13:29 file1
-rw-r--r-- 1 root root    0 Dec 21 13:29 file2

我发现许多文章中的解决方案声称可以在脚本中工作,但没有任何文章可以在交互式 shell 中工作。例如,许多人建议将其添加到脚本的顶部:

set -x

如果我在 shell 中输入此命令,命令将被打印(尽管不太好)到标准输出,但我还没有设法弄清楚如何将它们包含在输出重定向中。

我还看到很多人建议使用脚本来做到这一点。这是我最接近找到我要找的东西的一次,但我并不总是希望记录所有内容。我想控制哪些命令被重定向到文件。

有谁知道这个问题有一个好的解决方案吗?我愿意接受更多开箱即用的想法,只要它们对于日常使用来说不太笨重。

答案1

set -x 选项将脚本置于调试模式。实际命令回显到 stderr。因此,您需要将 stdout 和 stderr 重定向到某个文件。尝试这个
your_script.sh &> outputfile.txt

答案2

输出xtrace将发送至 stderr该命令的评估包括在执行重定向之前。

所以在:

set -x # or set -o xtrace
echo test 2> file

转到+ echo teststderr 要去的地方,然后 shellfile在 fd 2 上打开,然后运行echo test​​。如果你想要+ echo testfile,你需要:

{ echo test; } 2> file

这次,对命令组执行重定向,然后对echo test命令进行求值(并+ echo test写入 stderr,此时将转到file)。

请注意,某些 shell(例如 AT&T)ksh也会输出+ 2> file.在某些版本的mksh.

这也意味着该命令组中运行的任何命令的 stderr 都将转到file.要解决这个问题,您需要:

set -x
{
  cmd 2>&3 3>&-
} 3>&2 2> file

即保留原始 stderr 的副本(在 fd 3 上)并为命令组内的命令恢复它。

对于bash,另一种方法是使用$BASH_XTRACEFD特殊变量:

exec 7> file
BASH_XTRACEFD=7

set -x
echo test

如果你想要一个好的 xtrace输出,试试zsh。另请注意,它可以使用$PS4特殊变量进行自定义。

答案3

我认为最简单的解决方案是向您的.bashrc文件添加一个函数,如下所示:

my_run(){ echo $@ eval $@ }

source .bashrc添加该功能后务必。然后,使用您的示例,从命令行输入:

my_run ls -ahl >list_dir

如果您还想在屏幕上查看输出,请使用以下命令:

my_run ls -ahl | tee list_dir

如果您不想使用函数,可以通过以下几种方法从命令行执行此操作:

echo "ls -ahl" >list_dir; eval $@ >>list_dir

如果您还想在屏幕上看到输出,则其中任何一种都可以。

echo "ls -ahl" >list_dir; eval $@ | tee -a list_dir

echo "ls -ahl" | tee list_dir | bash >>list_dir

相关内容