如何调试 bash 脚本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/951336/
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 debug a bash script?
提问by corvus
Is there any way to debug a bash script? E.g something that prints a sort of execution log like "calling line 1", "calling line 2" etc.
有没有办法调试 bash 脚本?例如,打印某种执行日志的东西,如“调用第 1 行”、“调用第 2 行”等。
回答by Jonathan Leffler
sh -x script [arg1 ...]
bash -x script [arg1 ...]
These give you a trace of what is being executed. (See also 'Clarification' near the bottom of the answer.)
这些使您可以跟踪正在执行的内容。(另请参阅答案底部附近的“澄清”。)
Sometimes, you need to control the debugging within the script. In that case, as Cheetoremindedme, you can use:
有时,您需要控制脚本内的调试。在这种情况下,正如Cheeto提醒我的那样,您可以使用:
set -x
This turns debugging on. You can then turn it off again with:
这将打开调试。然后您可以再次关闭它:
set +x
(You can find out the current tracing state by analyzing $-
, the current flags, for x
.)
(您可以通过分析$-
,当前标志,为找出当前跟踪状态x
。)
Also, shells generally provide options '-n
' for 'no execution' and '-v
' for 'verbose' mode; you can use these in combination to see whether the shell thinks it could execute your script — occasionally useful if you have an unbalanced quote somewhere.
此外,shell 通常-n
为“不执行”和-v
“详细”模式提供选项“ ” ;你可以结合使用这些来查看 shell 是否认为它可以执行你的脚本——如果你在某处有不平衡的引用,偶尔会很有用。
There is contention that the '-x
' option in Bash is different from other shells (see the comments). The Bash Manualsays:
有人争论说-x
Bash中的 ' ' 选项与其他 shell 不同(请参阅注释)。该猛砸手册说:
-x
Print a trace of simple commands,
for
commands,case
commands,select
commands, and arithmeticfor
commands and their arguments or associated word lists after they are expanded and before they are executed. The value of thePS4
variable is expanded and the resultant value is printed before the command and its expanded arguments.
-X
在扩展之后和执行之前打印简单命令、
for
命令、case
命令、select
命令和算术for
命令及其参数或相关单词列表的痕迹。PS4
变量的值被扩展,结果值打印在命令及其扩展参数之前。
That much does not seem to indicate different behaviour at all. I don't see any other relevant references to '-x
' in the manual. It does not describe differences in the startup sequence.
这么多似乎根本没有表明不同的行为。我-x
在手册中没有看到任何其他与“ ”相关的参考资料。它不描述启动顺序的差异。
Clarification: On systems such as a typical Linux box, where '/bin/sh
' is a symlink to '/bin/bash
' (or wherever the Bash executable is found), the two command lines achieve the equivalent effect of running the script with execution trace on. On other systems (for example, Solaris, and some more modern variants of Linux), /bin/sh
is not Bash, and the two command lines would give (slightly) different results. Most notably, '/bin/sh
' would be confused by constructs in Bash that it does not recognize at all. (On Solaris, /bin/sh
is a Bourne shell; on modern Linux, it is sometimes Dash — a smaller, more strictly POSIX-only shell.) When invoked by name like this, the 'shebang' line ('#!/bin/bash
' vs '#!/bin/sh
') at the start of the file has no effect on how the contents are interpreted.
说明:在诸如典型的 Linux 机器之类的系统上,其中“ /bin/sh
”是“ ”的符号链接/bin/bash
(或找到 Bash 可执行文件的任何地方),这两个命令行实现了在执行跟踪打开的情况下运行脚本的等效效果。在其他系统(例如 Solaris 和一些更现代的 Linux 变体)上,/bin/sh
不是 Bash,并且两个命令行会给出(略有)不同的结果。最值得注意的是,' /bin/sh
' 会被 Bash 中它根本无法识别的结构所混淆。(在 Solaris 上,它/bin/sh
是一个 Bourne shell;在现代 Linux 上,它有时是 Dash — 一个更小、更严格的仅 POSIX 的 shell。)当这样调用时,'shebang' 行 (' #!/bin/bash
' vs '#!/bin/sh
'
The Bash manual has a section on Bash POSIX modewhich, contrary to a long-standing but erroneous version of this answer (see also the comments below), does describe in extensive detail the difference between 'Bash invoked as sh
' and 'Bash invoked as bash
'.
Bash 手册有一个关于Bash POSIX 模式的部分,与这个答案的长期存在但错误的版本相反(另见下面的评论),它确实详细描述了“Bash 调用为sh
”和“Bash 调用为”之间的区别bash
'。
When debugging a (Bash) shell script, it will be sensible and sane — necessary even — to use the shell named in the shebang line with the -x
option. Otherwise, you may (will?) get different behaviour when debugging from when running the script.
在调试(Bash)shell 脚本时,使用带有-x
选项的shebang 行中命名的shell 将是明智和理智的——甚至是必要的。否则,您可能(会?)在调试时获得与运行脚本时不同的行为。
回答by corvus
I've used the following methods to debug my script.
我使用以下方法来调试我的脚本。
set -e
makes the script stop immediately if any external program returns a non-zero exit status. This is useful if your script attempts to handle all error cases and where a failure to do so should be trapped.
set -e
如果任何外部程序返回非零退出状态,则使脚本立即停止。如果您的脚本尝试处理所有错误情况并且应该捕获执行失败的情况,这将非常有用。
set -x
was mentioned above and is certainly the most useful of all the debugging methods.
set -x
上面提到过,当然是所有调试方法中最有用的。
set -n
might also be useful if you want to check your script for syntax errors.
set -n
如果您想检查脚本是否存在语法错误,也可能很有用。
strace
is also useful to see what's going on. Especially useful if you haven't written the script yourself.
strace
也有助于了解发生了什么。如果您还没有自己编写脚本,则特别有用。
回答by Stabledog
This answer is valid and useful: https://stackoverflow.com/a/951352
这个答案有效且有用:https: //stackoverflow.com/a/951352
But, I find that the "standard" script debugging methods are inefficient, unintuitive, and hard to use. For those used to sophisticated GUI debuggers that put everything at your fingertips and make the job a breeze for easy problems (and possible for hard problems), these solutions aren't very satisfactory.
但是,我发现“标准”脚本调试方法效率低下、不直观且难以使用。对于那些习惯了复杂的 GUI 调试器的人来说,这些调试器将所有东西都放在您的指尖,让工作变得轻而易举,解决简单的问题(也可能解决困难的问题),这些解决方案并不是很令人满意。
What I do is use a combination of DDD and bashdb. The former executes the latter, and the latter executes your script. This provides a multi-window UI with the ability to step through code in context and view variables, stack, etc., without the constant mental effort to maintain context in your head or keep re-listing the source.
我所做的是使用 DDD 和 bashdb 的组合。前者执行后者,后者执行您的脚本。这提供了一个多窗口 UI,能够在上下文中单步执行代码并查看变量、堆栈等,而无需不断地在头脑中维护上下文或不断重新列出源代码。
There is guidance on setting that up here: http://ubuntuforums.org/showthread.php?t=660223
这里有关于设置的指导:http: //ubuntuforums.org/showthread.php?t=660223
回答by Cheeto
You can also write "set -x" within the script.
您还可以在脚本中编写“set -x”。
回答by Equation Solver
I found shellcheck utility and may be some folks find it interesting https://github.com/koalaman/shellcheck
我发现了 shellcheck 实用程序,可能有些人觉得它很有趣 https://github.com/koalaman/shellcheck
A little example:
一个小例子:
$ cat test.sh
ARRAY=("hello there" world)
for x in $ARRAY; do
echo $x
done
$ shellcheck test.sh
In test.sh line 3:
for x in $ARRAY; do
^-- SC2128: Expanding an array without an index only gives the first element.
fix the bug, first try...
修复错误,首先尝试...
$ cat test.sh
ARRAY=("hello there" world)
for x in ${ARRAY[@]}; do
echo $x
done
$ shellcheck test.sh
In test.sh line 3:
for x in ${ARRAY[@]}; do
^-- SC2068: Double quote array expansions, otherwise they're like $* and break on spaces.
Let's try again...
让我们再试一次...
$ cat test.sh
ARRAY=("hello there" world)
for x in "${ARRAY[@]}"; do
echo $x
done
$ shellcheck test.sh
find now!
立即查找!
It's just a small example.
这只是一个小例子。
回答by yantaq
回答by Dietrich Schroff
Use eclipse with the plugins shelled & basheclipse.
将 eclipse 与 shelled 和 basheclipse 插件一起使用。
https://sourceforge.net/projects/shelled/?source=directoryhttps://sourceforge.net/projects/basheclipse/?source=directory
https://sourceforge.net/projects/shelled/?source=directory https://sourceforge.net/projects/basheclipse/?source=directory
For shelled: Download the zip and import it into eclipse via help -> install new software : local archive For basheclipse: Copy the jars into dropins directory of eclipse
对于 shelled:下载 zip 并通过帮助将其导入 eclipse -> 安装新软件:本地存档 对于 basheclipse:将 jar 复制到 eclipse 的 dropins 目录中
Follow the steps provides https://sourceforge.net/projects/basheclipse/files/?source=navbar
按照提供的步骤https://sourceforge.net/projects/basheclipse/files/?source=navbar
I wrote a tutorial with many screenshots at http://dietrichschroff.blogspot.de/2017/07/bash-enabling-eclipse-for-bash.html
我在http://dietrichschroff.blogspot.de/2017/07/bash-enabling-eclipse-for-bash.html写了一个包含许多截图的教程
回答by Premraj
set +x = @ECHO OFF, set -x = @ECHO ON.
设置 +x = @ECHO 关闭,设置 -x = @ECHO 打开。
You can add -xv
option to the standard Shebang as follows:
您可以-xv
向标准 Shebang添加选项,如下所示:
#!/bin/bash -xv
-x
: Display commands and their arguments as they are executed.-v
: Display shell input lines as they are read.
-x
:在执行时显示命令及其参数。-v
: 在读取时显示 shell 输入行。
ltrace
is another Linux Utility similar to strace
. However, ltrace
lists all the library calls being called in an executable or a running process. Its name itself comes from library-call tracing. For example:
ltrace
是另一个类似于strace
. 但是,ltrace
列出在可执行文件或正在运行的进程中调用的所有库调用。它的名字本身来自库调用跟踪。例如:
ltrace ./executable <parameters>
ltrace -p <PID>
回答by abadjm
I built a Bash debugger. Just give it a try. I hope it will help https://sourceforge.net/projects/bashdebugingbash
我构建了一个 Bash 调试器。试试吧。我希望它会有所帮助 https://sourceforge.net/projects/bashdebugingbash
回答by Nan Xiao
I think you can try this Bash debugger: http://bashdb.sourceforge.net/.
我想你可以试试这个 Bash 调试器:http: //bashdb.sourceforge.net/。