Bash set -x echo重定向以及命令

时间:2013-03-12 16:20:13

标签: bash pipe io-redirection

我正在编写一个Bash脚本,我希望所有命令在发生时都能回显。我知道我需要使用set -xset +x分别关闭和打开此行为(SOF post here)。但是,它不会回显所有内容,即I / O重定向。

例如,假设我有一个非常简单的Bash脚本:

set -x
./command1 > output1
./command2 arg1 arg2 > output2

这将是输出

+ ./command1
+ ./command2 arg1 arg2

Bash没有回显我的stdout重定向到 output1 output2 。为什么是这样?我怎样才能实现这种行为?也许我必须在脚本中设置shopt选项吗?

注意:我还注意到管道无法按预期打印。例如,如果我要使用此命令:

set -x
./command3 | tee output3

我会得到这个输出:

+ tee output3
+ ./command3

如何使命令完全按照它们的编写方式进行回显,而不是让脚本重新排序管道?

3 个答案:

答案 0 :(得分:6)

当使用某些结构时,set -x和DEBUG陷阱都不会提供完整信息。

例如:

ex1.sh

for i in a b c
do
  echo $i # Where does the output go?
done > outfile # Here!

ex2.sh

c="this"
case "$c" in
  this) echo sure ;; # Where does the output go?
  that) echo okay ;;
esac > choice # Here!

ex3.sh

what="up"
while [ "$what" = "up" ]
do
    echo "Going down!" # Where does the output go?
    what="down"
    echo "Newton rulezzz!" > thelaw
done > trying # Here!

以及更多这样的,更不用说各种嵌套变体了。我不知道一个简单的方法来处理这些,除了进入完整的Bash脚本解析的土地,这是一个雷区......

编辑:如果不需要特定于Bash的功能,并且向后兼容Bourne shell,Korn shell(ksh,使用版本93u + 2012-08-01测试)在显示重定向信息方面做得更好:

$ ksh -x ex1.sh 
+ 1> outfile
+ echo a
+ echo b
+ echo c

$ ksh -x ex2.sh 
+ c=this
+ 1> choice
+ echo sure

$ ksh -x ex3.sh 
+ what=up
+ 1> trying
+ [ up '=' up ]
+ echo 'Going down!'
+ what=down
+ echo 'Newton rulezzz!'
+ 1> thelaw
+ [ down '=' up ]

答案 1 :(得分:6)

您应该使用set -v

  

-v在读取时打印shell输入行。

输出似乎符合您的期望。

$ set -v
$ ./command1 > output1
./command1 > output1
sh: ./command1: No such file or directory
$ ./command2 arg1 arg2 > output2
./command2 arg1 arg2 > output2
sh: ./command2: No such file or directory
$ ./command3 | tee output3
./command3 | tee output3
sh: ./command3: No such file or directory

答案 2 :(得分:4)

set -x无法实现。您唯一的选择是通过DEBUG陷阱查看当前命令。

trap 'printf %s\\n "$BASH_COMMAND" >&2' DEBUG

这不会显示set -x的准确参数。将它们组合在一起可以为您提供全面的图片,尽管它有很多调试输出。