在一个shell脚本,我如何回显所有shell命令调用和展开任何变量名?

例如,给定以下一行:

ls $DIRNAME

我希望脚本运行该命令并显示以下内容

ls /full/path/to/some/dir

目的是保存所有调用的shell命令及其参数的日志。是否有更好的方法来生成这样的日志?


当前回答

根据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十五

其他回答

另一种选择是在你的脚本顶部放置"-x",而不是在命令行上:

$ cat ./server
#!/bin/bash -x
ssh user@server

$ ./server
+ ssh user@server
user@server's password: ^C
$

Set -x会得到你想要的。

下面是一个示例shell脚本来演示:

#!/bin/bash
set -x #echo on

ls $PWD

这将展开所有变量,并在输出命令之前打印完整的命令。

输出:

+ ls /home/user/
file1.txt file2.txt
$ cat exampleScript.sh
#!/bin/bash
name="karthik";
echo $name;

bash -x exampleScript.sh

输出结果如下:

根据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十五

为了允许复合命令被回显,我使用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