调试中,Shell选项“-v”和“-x”的区别是什么?

7

-x 表示跟踪执行过程,-v 表示在执行前将整个命令打印到标准输出。

在研究时,我发现 bash -x "扩展命令",而 -v 在执行之前将整个命令打印到标准输出。

在测试时,我发现唯一的区别是 bash -v <scriptname> 还会显示每个命令的注释。

这是唯一的区别吗?有人可以解释一下吗?


为什么要给我负评? - Anonymous
1
我没有投票。请参见:help set | grep '^ *-[xv]' - Cyrus
2个回答

7

根据手册:

  -v  Print shell input lines as they are read.
  -x  Print commands and their arguments as they are executed.

当查看管道命令的处理方式时,您可以看到这种区别:

$ set -v
$ echo "Hello World" | sed 's/World/Earth/'
echo "Hello World" | sed 's/World/Earth/'
Hello Earth

对比:

$ set -x
$ echo "Hello World" | sed 's/World/Earth/'
    + sed s/World/Earth/
    + echo 'Hello World'
    Hello Earth

此外,似乎xtrace (-x)使用$PS4变量,而verbose (-v)则不使用。

0

对于简单的命令,输出非常相似,但似乎set -v(冗长)只是重复输入行,而set -x(xtrace)显示变量扩展和单词拆分后运行的命令等。考虑下面的示例,我认为在调试shell脚本时同时使用两者是值得的:verbose帮助浏览脚本并显示命令的意图,而xtrace则更详细地显示实际运行的内容。从现在开始,我将在调试脚本时使用set -vx。这些差异在具有变量、命令列表、函数等示例中变得更加明显:

$ set +vx           # both disabled (default for most people)
$ foo=(1 2 '3 three')
$ printf 'foo is %s\n' "${foo[@]}" && echo ''
foo is 1
foo is 2
foo is 3 three

$ set -v            # verbose
$ printf 'foo is %s\n' "${foo[@]}" && echo ''
printf 'foo is %s\n' "${foo[@]}" && echo ''
foo is 1
foo is 2
foo is 3 three

$ set +v
set +v
$ set -x            # xtrace
$ printf 'foo is %s\n' "${foo[@]}" && echo ''
+ printf 'foo is %s\n' 1 2 '3 three'
foo is 1
foo is 2
foo is 3 three
+ echo ''

$ set +x
+ set +x
$ set -vx           # both verbose and xtrace
$ printf 'foo is %s\n' "${foo[@]}" && echo ''
printf 'foo is %s\n' "${foo[@]}" && echo ''  # from verbose, input line simply repeated
+ printf 'foo is %s\n' 1 2 '3 three'         # from xtrace, command list split, variables substituted
foo is 1
foo is 2
foo is 3 three
+ echo ''

# word splitting behaviour is made more obvious by xtrace
# (note the array is unquoted now)
$ printf 'foo is %s\n' ${foo[@]} && echo ''
printf 'foo is %s\n' ${foo[@]} && echo ''
+ printf 'foo is %s\n' 1 2 3 three           # missing single quotes due to word splitting
foo is 1
foo is 2
foo is 3
foo is three                                 # !
+ echo ''

# function with both verbose and xtrace set
$ function bar { printf '%s\n' "${foo[@]}"; }
function bar { printf '%s\n' "${foo[@]}"; }  # verbose repeats definition, nothing output by xtrace
$ bar
bar                                          # verbose repeats function call
+ bar                                        # xtrace shows commands run
+ printf '%s\n' 1 2 '3 three'
1
2
3 three

附注:其他的 shells

上述示例来自于 bash。在我的测试中,posix dash 的输出对于这两个选项非常相似,尽管在该 shell 中当然不可能使用数组。zsh 通过在前面加上行号略微扩展了 xtrace 输出,但其行为基本相似(尽管在这里,它的不同的单词拆分行为是显而易见的):

$ zsh
% foo=(1 2 '3 three')
% set -vx
% printf 'foo is %s\n' ${foo[@]} && echo ''
printf 'foo is %s\n' ${foo[@]} && echo ''    # verbose repeats input command
+zsh:14> printf 'foo is %s\n' 1 2 '3 three'  # xtrace prints expanded command with line number
foo is 1
foo is 2
foo is 3 three
+zsh:14> echo ''


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接