我在 bash 中的某些脚本中遇到一些问题,涉及错误和意外行为。我想调查问题的原因,以便我可以应用修复程序。有没有办法可以为 bash 开启某种“调试模式”,以获取更多信息?
答案1
使用以下命令启动 bash 脚本bash -x ./script.sh
或添加到脚本中set -x
以查看调试输出。
bash
4.1 或更高版本的附加功能:
如果要将调试输出写入单独的文件,请将其添加到脚本中:
exec 5> debug_output.txt
BASH_XTRACEFD="5"
看:https://stackoverflow.com/a/25593226/3776858
如果您想查看行号,请添加以下内容:
PS4='$LINENO: '
如果您有权访问
logger
命令,那么您可以使用它通过系统日志写入调试输出,其中包含时间戳、脚本名称和行号:
#!/bin/bash
exec 5> >(logger -t $0)
BASH_XTRACEFD="5"
PS4='$LINENO: '
set -x
# Place your code here
您可以使用命令选项-p
来logger
设置单独的设施和级别,以通过本地系统日志将输出写入其自己的日志文件。
答案2
使用set -x
我总是使用set -x
和set +x
。您可以将想要查看其发生情况的区域包裹起来,以提高/降低详细程度。
#!/bin/bash
set -x
..code to debug...
set +x
日志4bash
另外,如果您已经完成了开发工作并且熟悉名为 log4j、log4perl 等的记录器的风格,那么您可能想要使用日志4bash。
摘抄让我们面对现实吧——普通的旧回声并不能解决问题。 log4bash 是一种为 Bash 脚本提供更好的日志记录的尝试(即让 Bash 中的日志记录变得更少)。
从那里您可以在 Bash 脚本中执行以下操作:
#!/usr/bin/env bash
source log4bash.sh
log "This is regular log message... log and log_info do the same thing";
log_warning "Luke ... you turned off your targeting computer";
log_info "I have you now!";
log_success "You're all clear kid, now let's blow this thing and go home.";
log_error "One thing's for sure, we're all gonna be a lot thinner.";
# If you have figlet installed -- you'll see some big letters on the screen!
log_captains "What was in the captain's toilet?";
# If you have the "say" command (e.g. on a Mac)
log_speak "Resistance is futile";
产生这种类型的输出:
日志4sh
如果您需要更便携的东西,还有较旧的log4sh
.与 类似log4bash
,可在此处获取:
答案3
有一个 bash 调试器,bash数据库,这是许多发行版上的可安装包。它使用 bash 内置的扩展调试模式 ( shopt -s extdebug
)。它看起来很像gdb;下面是一个示例会话,以供大家参考:
$ ls
1st.JPG 2ndJPG.JPG
$ cat ../foo.sh
for f in *.JPG
do
newf=${f/JPG/jpg}
mv $f $newf
done
$ bashdb ../foo.sh
(foo.sh:1):
1: for f in *.JPG
bashdb<0> next
(foo.sh:3):
3: newf=${f/JPG/jpg}
bashdb<1> next
(foo.sh:4):
4: mv $f $newf
与 gdb 中一样,该语句仅显示前它即将被执行。因此,我们可以检查变量以了解该语句在执行之前将执行什么操作。
bashdb<2> print $f $newf
1st.JPG 1st.jpg
bashdb<3> next
(foo.sh:1):
1: for f in *.JPG
bashdb<4> next
(foo.sh:3):
3: newf=${f/JPG/jpg}
bashdb<5> next
(foo.sh:4):
4: mv $f $newf
bashdb<6> print $f $newf
2ndJPG.JPG 2ndjpg.JPG
这不是我们想要的!我们再看一下参数扩展。
bashdb<7> print $f ${f/JPG/jpg}
2ndJPG.JPG 2ndjpg.JPG
bashdb<8> print $f ${f/JPG$/jpg}
2ndJPG.JPG 2ndJPG.JPG
bashdb<9> print $f ${f/%JPG/jpg}
2ndJPG.JPG 2ndJPG.jpg
好的,这有效。让我们设置newf
为正确的值。
bashdb<10> eval newf=${f/%JPG/jpg}
$? is 0
bashdb<11> print $f $newf
2ndJPG.JPG 2ndJPG.jpg
看起来不错。继续剧本。
bashdb<12> next
Debugged program terminated normally. Use q to quit or R to restart.
$ ls
1st.jpg 2ndJPG.jpg
答案4
使用Eclipse
您可以使用 Eclipse 和 Shelled 的组合环境以及下面链接的“_DEBUG.sh”脚本。
- Eclipse 带壳插件:
http://sourceforge.net/projects/shelled/files/shelled/update/ - bash 调试器 - 仅适用于 shell:
http://sourceforge.net/projects/basheclipse/
切换外壳
默认情况下,Shelled 开发工具用作/bin/dash
解释器。我将其更改为/bin/bash
与网络上和我的环境中的大多数 shell 示例具有更好的兼容性。
笔记:您可以通过以下方式更改此设置:窗户->偏爱->外壳脚本->口译员
设置说明
调试器包包含使用脚本进行脚本调试的步骤_DEBUG.sh
,基本上是(readme.txt):
- 创建Shell脚本项目: 文件->新的->其他->外壳脚本->Shell 脚本项目向导。
- 创建 Bash 脚本文件:文件->新的->文件。对于本示例,它将是
script.sh
.扩展名应该是“.sh”,并且是必须的。- 将文件复制
_DEBUG.sh
到项目文件夹。将以下文本插入到文件顶部
script.sh
:. _DEBUG.sh
如果该文件是在 Microsoft Windows 中创建的,请务必执行文件->将行分隔符转换为->Unix。
设置调试启动配置:跑步->调试配置->bash 脚本...这里有2个字段需要设置:
a) “Bash script:” - Eclipse 工作区中到要调试的 Bash 脚本的路径。
e) “调试器端口:”33333切换到“调试”透视图。启动调试会话。
script.sh
从 bash shell启动。
bash 调试用户界面
这个 bash 调试器具有标准编程调试器的全部功能,例如:
- 断点切换
- 单步操作
- 步入、步出、步过功能和子程序
- 在脚本运行时随时检查代码或变量
带壳的(Shell 脚本编辑器)IDE(集成开发环境)还有一个额外的好处,即在编写脚本时执行上下文检查、突出显示和缩进。如果它没有正确缩进,您可能会立即能够在那里标记/本地化许多错误。
然后还有其他 IDE 优势例如:
- TODO 任务列表
- 迈林任务
- 书签列表
- 多窗口编辑
- 远程共享环境