23

在 shell 脚本中,出于状态和调试原因,我想回显一些主要(长时间运行)命令。set -x我知道我可以使用or为所有命令启用回显set -v。但我不想看到所有命令(特别是 echo 命令)。有没有办法只为一个命令打开回声?

我可以这样做,但这很丑陋,也与这条线相呼应set +x

#!/bin/sh

dir=/tmp
echo List $dir

set -x
ls $dir
set +x

echo Done!

有一个更好的方法吗?

4

4 回答 4

30

以每次进程为代价,您可以使用:

(set -x; ls $dir)

这会在子 shell 中运行命令,因此set -x只会影响括号内的内容。您无需编码或查看set +x. 当我需要进行选择性跟踪时,我会使用它。

于 2012-10-04T00:47:02.513 回答
4

使用这个功能怎么样?

runtraced() {
    echo "$@"
    "$@"
}

dosomething
runtraced dosomethingelse
于 2012-10-05T01:53:07.110 回答
2

根据 Jonathan Leffler 的回答,这以相同的方式工作,只是更清楚一点,因为在命令之后需要注意。但是您需要指定应该使用哪个 shell。这是 sh 的示例:

sh -xc ls $dir
于 2012-10-05T01:47:50.860 回答
2

一个简单的方法是使用一个heredoc和一个未解释的字符串。它是 POSIX 可移植且快速的:

...
% cmd='ls ${dir}'
% sh -x <<_EOF_
> ${cmd}
> _EOF_
...

您可以通过这种方式构建整个脚本,根据需要以编程方式解析和/或修改它们,将它们保存到 shell 变量并从 shell 变量中调用它们,并在另一个脚本或 shell 函数中运行它们:

...
% script="$(cat </some/entire/script.sh)"
% script="$(pipeline | processing | on | ${script})"    
% sh -x <<_EOF_ 2>&1 | grep ${specific_cmds_Im_looking_for}
> ${script}
> _EOF_
<desired output>

在我对 POSIX 兼容方式的回答中,查看是否在 sh 脚本中定义了一个函数,我更详细地描述了这个方法和原因。在 Stack Exchange 上,我非常彻底地讨论了如何heredoc使用它来解决一些烦人的引用问题,以回答Is there a way to get actual (uninterpreted) shell arguments in a function or script? .

-麦克风

于 2013-11-23T12:21:10.160 回答