在shell脚本中,我想回顾一些主要(长时间运行)命令的状态和调试原因。我知道我可以使用set -x
或set -v
为所有命令启用回显。但我不想看到所有的命令(特别是不是echo命令)。有没有办法只为一个命令打开回声?
我可以这样做,但这很丑陋并且也与set +x
行相呼应:
#!/bin/sh
dir=/tmp
echo List $dir
set -x
ls $dir
set +x
echo Done!
有更好的方法吗?
答案 0 :(得分:23)
以每个场合的流程为代价,您可以使用:
(set -x; ls $dir)
这在子shell中运行命令,因此set -x
仅影响括号内的内容。您无需编码或查看set +x
。当我需要进行选择性追踪时,我会使用它。
答案 1 :(得分:3)
如何使用此功能?
runtraced() {
echo "$@"
"$@"
}
dosomething
runtraced dosomethingelse
答案 2 :(得分:2)
根据Jonathan Leffler的回答,这个方法的工作方式相同,只是更清楚一点,因为命令后需要注意。但是您需要指定应该使用哪个shell。这是sh:
的一个例子sh -xc ls $dir
答案 3 :(得分:1)
一种简单的方法是使用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 compliant way to see if a function is defined in an sh script的回答中,我更详细地描述了这种情况。在Stack Exchange中,我非常彻底地讨论heredoc
如何在回答Is there a way to get actual (uninterpreted) shell arguments in a function or script?时解决一些恼人的引用问题。
-Mike