bash 如何在执行时回显 shell 命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2853803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to echo shell commands as they are executed
提问by Hyman Nock
In a shell script, how do I echo all shell commands called and expand any variable names?
在 shell 脚本中,如何回显所有调用的 shell 命令并扩展任何变量名称?
For example, given the following line:
例如,给定以下行:
ls $DIRNAME
I would like the script to run the command and display the following
我希望脚本运行命令并显示以下内容
ls /full/path/to/some/dir
The purpose is to save a log of all shell commands called and their arguments. Is there perhaps a better way of generating such a log?
目的是保存所有调用的 shell 命令及其参数的日志。也许有更好的方法来生成这样的日志?
回答by Tom
set -x
or set -o xtrace
expands variables and prints a little + sign before the line.
set -x
或set -o xtrace
扩展变量并在行前打印一个小 + 号。
set -v
or set -o verbose
does not expand the variables before printing.
set -v
或set -o verbose
在打印前不扩展变量。
Use set +x
and set +v
to turn off the above settings.
使用set +x
和set +v
关闭上述设置。
On the first line of the script, one can put #!/bin/sh -x
(or -v
) to have the same effect as set -x
(or -v
) later in the script.
在脚本的第一行,一个可以把#!/bin/sh -x
(或-v
)有同样的效果set -x
(或-v
)后面的脚本。
The above also works with /bin/sh
.
以上也适用于/bin/sh
.
See the bash-hackers' wiki on set
attributes, and on debugging.
有关set
属性和调试,请参阅 bash-hackers 的 wiki 。
$ cat shl
#!/bin/bash
DIR=/tmp/so
ls $DIR
$ bash -x shl
+ DIR=/tmp/so
+ ls /tmp/so
$
回答by radman
set -x
will give you what you want.
set -x
会给你你想要的。
Here is an example shell script to demonstrate:
下面是一个示例 shell 脚本来演示:
#!/bin/bash
set -x #echo on
ls $PWD
This expands all variables and prints the full commands before output of the command.
这将扩展所有变量并在命令输出之前打印完整命令。
Output:
输出:
+ ls /home/user/
file1.txt file2.txt
回答by Soth
I use a function to echo and run the command:
我使用一个函数来回显并运行命令:
#!/bin/bash
# Function to display commands
exe() { echo "$ $@" ; "$@" ; }
exe echo hello world
Which outputs
哪些输出
$ echo hello world
hello world
For more complicated commands pipes, etc., you can use eval:
对于更复杂的命令管道等,可以使用 eval:
#!/bin/bash
# Function to display commands
exe() { echo "$ ${@/eval/}" ; "$@" ; }
exe eval "echo 'Hello, World!' | cut -d ' ' -f1"
Which outputs
哪些输出
$ echo 'Hello, World!' | cut -d ' ' -f1
Hello
回答by shuckc
You can also toggle this for select lines in your script by wrapping them in set -x
and set +x
, for example,
您还可以通过将它们包装在set -x
和set +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
回答by bhassel
shuckc's answerfor echoing select lines has a few downsides: you end up with the following set +x
command being echoed as well, and you lose the ability to test the exit code with $?
since it gets overwritten by the set +x
.
shuckc对回显选择行的回答有一些缺点:您最终set +x
也会回显以下命令,并且您失去了测试退出代码的能力,$?
因为它被set +x
.
Another option is to run the command in a subshell:
另一种选择是在子shell中运行命令:
echo "getting URL..."
( set -x ; curl -s --fail $URL -o $OUTFILE )
if [ $? -eq 0 ] ; then
echo "curl failed"
exit 1
fi
which will give you output like:
这将为您提供如下输出:
getting URL...
+ curl -s --fail http://example.com/missing -o /tmp/example
curl failed
This does incur the overhead of creating a new subshell for the command, though.
不过,这确实会产生为命令创建新子 shell 的开销。
回答by nooj
Another option is to put "-x" at the top of your script instead of on the command line:
另一种选择是将“-x”放在脚本的顶部而不是命令行上:
$ cat ./server
#!/bin/bash -x
ssh user@server
$ ./server
+ ssh user@server
user@server's password: ^C
$
回答by Afriza N. Arief
According to TLDP's Bash Guide for Beginners: Chapter 2. Writing and debugging scripts:
根据TLDP的Bash 初学者指南:第 2 章编写和调试脚本:
2.3.1. Debugging on the entire script
$ bash -x script1.sh
...
There is now a full-fledged debugger for Bash, available at SourceForge. These debugging features are available in most modern versions of Bash, starting from 3.x.
2.3.2. Debugging on part(s) of the script
set -x # Activate debugging from here w set +x # Stop debugging from here
...
Table 2-1. Overview of set debugging options
2.3.1. 调试整个脚本
$ bash -x script1.sh
...
现在有一个成熟的 Bash 调试器,可在SourceForge 获得。这些调试功能在大多数现代版本的 Bash 中都可用,从 3.x 开始。
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.
...
Alternatively, these modes can be specified in the script itself, by adding the desired options to the first line shell declaration. Options can be combined, as is usually the case with UNIX commands:
#!/bin/bash -xv
...
或者,可以在脚本本身中指定这些模式,方法是将所需的选项添加到第一行 shell 声明中。可以组合选项,就像 UNIX 命令的情况一样:
#!/bin/bash -xv
回答by Alan
Type "bash -x" on the command line before the name of the Bash script. For instance, to execute foo.sh, type:
在命令行上的 Bash 脚本名称之前键入“bash -x”。例如,要执行 foo.sh,请键入:
bash -x foo.sh
回答by RenRen
You can executea Bash script in debug mode with the -x
option.
您可以使用选项在调试模式下执行Bash 脚本。-x
This will echo all the commands.
这将回显所有命令。
bash -x example_script.sh
# Console output
+ cd /home/user
+ mv text.txt mytext.txt
You can also save the -x option in the script. Just specify the -x
option in the shebang.
您还可以在脚本中保存 -x 选项。只需-x
在shebang中指定选项即可。
######## 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
回答by zzapper
For zsh, echo
对于 zsh,回显
setopt VERBOSE
And for debugging,
为了调试,
setopt XTRACE