在一个shell脚本,我如何回显所有shell命令调用和展开任何变量名?
例如,给定以下一行:
ls $DIRNAME
我希望脚本运行该命令并显示以下内容
ls /full/path/to/some/dir
目的是保存所有调用的shell命令及其参数的日志。是否有更好的方法来生成这样的日志?
在一个shell脚本,我如何回显所有shell命令调用和展开任何变量名?
例如,给定以下一行:
ls $DIRNAME
我希望脚本运行该命令并显示以下内容
ls /full/path/to/some/dir
目的是保存所有调用的shell命令及其参数的日志。是否有更好的方法来生成这样的日志?
当前回答
另一种选择是在你的脚本顶部放置"-x",而不是在命令行上:
$ cat ./server
#!/bin/bash -x
ssh user@server
$ ./server
+ ssh user@server
user@server's password: ^C
$
其他回答
对于zsh,使用echo
setopt VERBOSE
为了调试,
setopt XTRACE
对于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命令行选项设置。
根据TLDP的Bash初学者指南:第2章。编写和调试脚本:
2.3.1. 调试整个脚本 $ bash -x script1.sh ... 现在在SourceForge上有一个成熟的Bash调试器。从3.x开始,这些调试特性在大多数现代版本的Bash中都可以使用。 2.3.2. 调试脚本的一部分 set -x #从这里激活调试 w set +x #从这里停止调试 ... 表2 - 1。set调试选项概述
Short | Long notation | Result
-------+---------------+--------------------------------------------------------------
set -f | set -o noglob | Disable file name generation using metacharacters (globbing).
set -v | set -o verbose| Prints shell input lines as they are read.
set -x | set -o xtrace | Print command traces before executing command.
... 或者,这些模式可以在脚本本身中指定 在第一行shell声明中添加所需的选项。 选项可以组合,就像UNIX命令通常的情况一样: # !/bin/bash十五
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
$
为了允许复合命令被回显,我使用eval加上Soth的exe函数来回显和运行命令。这对于管道命令非常有用,否则这些管道命令只显示不显示或只显示管道命令的初始部分。
没有eval:
exe() { echo "\$ $@" ; "$@" ; }
exe ls -F | grep *.txt
输出:
$
file.txt
eval:
exe() { echo "\$ $@" ; "$@" ; }
exe eval 'ls -F | grep *.txt'
的输出
$ exe eval 'ls -F | grep *.txt'
file.txt