如何在执行外壳命令时回显它们

ls $DIRNAME
ls /full/path/to/some/dir

答案

set -xset -o xtrace扩展变量并在该行之前打印一点 + 号。

set -vset -o verbose不会在打印之前扩展变量。

使用set +xset +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
$

set -x将为您提供所需的内容。

这是一个示例 shell 脚本来演示:

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

ls $PWD

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

输出:

+ ls /home/user/
file1.txt file2.txt

我使用一个函数来回显并运行命令:

#!/bin/bash
# Function to display commands
exe() { echo "\$ $@" ; "$@" ; }

exe echo hello world

哪个输出

$ echo hello world
hello world

对于更复杂的命令管道等,可以使用 eval:

#!/bin/bash
# Function to display commands
exe() { echo "\$ ${@/eval/}" ; "$@" ; }

exe eval "echo 'Hello, World!' | cut -d ' ' -f1"

哪个输出

$  echo 'Hello, World!' | cut -d ' ' -f1
Hello

您还可以通过将它们包装在set -xset +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

shuckc回显选择行的答案有一些缺点:您最终还会回显以下set +x命令,并且您失去了使用$?测试退出代码的能力$?因为它被set +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 的开销。

另一个选择是在脚本的顶部而不是在命令行的顶部放置 “-x”:

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

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

根据TLDPBash 初学者指南:第 2 章。编写和调试脚本

2.3.1。在整个脚本上调试

$ bash -x script1.sh

...

现在,可以在SourceForge 上使用 Bash 的完整调试器。从 3.x 开始,大多数现代版本的 Bash 中都提供了这些调试功能。

2.3.2。在脚本的一部分上进行调试

set -x            # Activate debugging from here
w
set +x            # Stop debugging from here

...

表 2-1。设置调试选项概述

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 -xv

在 Bash 脚本名称之前的命令行上键入 “bash -x”。例如,要执行 foo.sh,请输入:

bash -x foo.sh

您可以使用-x选项在调试模式下执行 Bash 脚本。

这将回显所有命令。

bash -x example_script.sh

# Console output
+ cd /home/user
+ mv text.txt mytext.txt

您也可以将 - x 选项保存在脚本中 。只需在 shebang 中指定-x选项即可。

######## example_script.sh ###################
#!/bin/bash -x

cd /home/user
mv text.txt mytext.txt

##############################################

./example_script.sh

# Console output
+ cd /home/user
+ mv text.txt mytext.txt

对于 zsh,回显

setopt VERBOSE

对于调试,

setopt XTRACE