在 shell 脚本中,出于状态和调试原因,我想回显一些主要(长时间运行)命令。set -x
我知道我可以使用or为所有命令启用回显set -v
。但我不想看到所有命令(特别是 echo 命令)。有没有办法只为一个命令打开回声?
我可以这样做,但这很丑陋,也与这条线相呼应set +x
:
#!/bin/sh
dir=/tmp
echo List $dir
set -x
ls $dir
set +x
echo Done!
有一个更好的方法吗?
以每次进程为代价,您可以使用:
(set -x; ls $dir)
这会在子 shell 中运行命令,因此set -x
只会影响括号内的内容。您无需编码或查看set +x
. 当我需要进行选择性跟踪时,我会使用它。
使用这个功能怎么样?
runtraced() {
echo "$@"
"$@"
}
dosomething
runtraced dosomethingelse
根据 Jonathan Leffler 的回答,这以相同的方式工作,只是更清楚一点,因为在命令之后需要注意。但是您需要指定应该使用哪个 shell。这是 sh 的示例:
sh -xc ls $dir
一个简单的方法是使用一个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? .
-麦克风