-x
表示跟踪执行过程,-v
表示在执行前将整个命令打印到标准输出。
在研究时,我发现 bash -x
"扩展命令",而 -v
在执行之前将整个命令打印到标准输出。
在测试时,我发现唯一的区别是 bash -v <scriptname>
还会显示每个命令的注释。
这是唯一的区别吗?有人可以解释一下吗?
根据手册:
-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
对于简单的命令,输出非常相似,但似乎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 ''
help set | grep '^ *-[xv]'
- Cyrus