在一个shell脚本,我如何回显所有shell命令调用和展开任何变量名?
例如,给定以下一行:
ls $DIRNAME
我希望脚本运行该命令并显示以下内容
ls /full/path/to/some/dir
目的是保存所有调用的shell命令及其参数的日志。是否有更好的方法来生成这样的日志?
在一个shell脚本,我如何回显所有shell命令调用和展开任何变量名?
例如,给定以下一行:
ls $DIRNAME
我希望脚本运行该命令并显示以下内容
ls /full/path/to/some/dir
目的是保存所有调用的shell命令及其参数的日志。是否有更好的方法来生成这样的日志?
当前回答
Shuckc对回显选择行的回答有一些缺点:您最终也会回显以下set +x命令,并且您失去了使用$?因为它被集合+x覆盖了。
另一种选择是在子shell中运行命令:
echo "getting URL..."
( set -x ; curl -s --fail $URL -o $OUTFILE )
if [ $? -eq 0 ] ; then
echo "curl failed"
exit 1
fi
这将给你输出如下:
getting URL...
+ curl -s --fail http://example.com/missing -o /tmp/example
curl failed
但是,这确实会导致为命令创建新子shell的开销。
其他回答
对于csh和tcsh,可以设置verbose或设置echo(甚至可以同时设置两者,但大多数时候可能会导致一些重复)。
verbose选项几乎打印您键入的shell表达式。
echo选项更能说明通过生成将执行什么。
http://www.tcsh.org/tcsh.html/Special_shell_variables.html#verbose
http://www.tcsh.org/tcsh.html/Special_shell_variables.html#echo
特殊的壳变量
详细的 如果设置,则导致在历史替换(如果有)之后打印每个命令的单词。由-v命令行选项设置。
回声 如果设置了,每个命令及其参数都会在执行之前被回显。对于非内置命令,所有展开都发生在回显之前。内置命令在命令和文件名替换之前被回显,因为这些替换是选择性地完成的。由-x命令行选项设置。
Set -x或Set -o xtrace展开变量并在行前打印一个小的+号。
Set -v或Set -o verbose不会在打印之前展开变量。
使用set +x和set +v关闭上述设置。
在脚本的第一行,可以输入#!/bin/sh -x(或-v)与后面脚本中的set -x(或-v)具有相同的效果。
上面的代码也适用于/bin/sh。
关于set属性和调试,请参阅bash-hackers的wiki。
$ cat shl
#!/bin/bash
DIR=/tmp/so
ls $DIR
$ bash -x shl
+ DIR=/tmp/so
+ ls /tmp/so
$
$ cat exampleScript.sh
#!/bin/bash
name="karthik";
echo $name;
bash -x exampleScript.sh
输出结果如下:
Set -x会得到你想要的。
下面是一个示例shell脚本来演示:
#!/bin/bash
set -x #echo on
ls $PWD
这将展开所有变量,并在输出命令之前打印完整的命令。
输出:
+ ls /home/user/
file1.txt file2.txt
您还可以通过将脚本中的选定行包装在set -x和set +x中来切换此选项,例如,
#!/bin/bash
...
if [[ ! -e $OUT_FILE ]];
then
echo "grabbing $URL"
set -x
curl --fail --noproxy $SERV -s -S $URL -o $OUT_FILE
set +x
fi