如何调试bash脚本?


31

有什么方法可以在不使用echo和logging的情况下调试bash脚本?

我说的是使用断点之类的东西。

Answers:



20

有几种不同的方法,即:

  • 使用-x选项运行脚本

    bash -x yourscript.sh
  • set -x在Shebang之后#!/bin/bash和脚本开始之前的脚本文件开头添加新行,set -v将显示shell输入行,set -x显示已执行的命令和参数

  • 将您的脚本文件的shebang替换为 #!/bin/bash -xv




4

您可以使用此小功能放入“控制台”:

function debug
{
    echo "#############|  Entering DEBUG mode  |####################";
    cmd=""
    while [[ $cmd != "exit" ]]; do
        read -p "> " cmd
        case "$cmd" in
            vars ) ( set -o posix ; set );;
            exit ) ;;
            * ) eval "$cmd";;
        esac
    done
    echo "#############|  End of DEBUG mode |####################";
}

然后,在您的脚本中(示例):

for file in *; do
...
   if [[ $file == "strange_case.txt" ]]; then
       # break the code here to analyze:
       debug
   fi
...
done

它将接受任何命令,保持局部变量完整。要退出“调试”模式,请键入“退出”(它不会退出脚本),它将继续执行代码。如果在循环内使用“调试”,则每次都会停止。您可以将其包装在“ if”中(如上例所示),或创建“ watch”函数:

function debug_watch
{
    if [[ $1 == $2 ]]; then
        debug
    fi
}

# And Use it:

debug_watch "$file" "strange_case.txt"

我还添加了“ vars”命令,该命令将转储所有可用变量及其值。您也可以添加自己的自定义命令。

我在几分钟内完成了代码,因此使用时需要您自担风险。请注意,在调试模式下可以执行任何命令,因此,如果将其留在生产脚本中,则会带来安全隐患。


3
避免使用大写的变量名。您的风险将覆盖特殊的Shell变量和环境变量。另外,请确保在将参数扩展用作参数时引用它们,以免在结果中出现单词拆分和路径名扩展。例如* ) eval "$cmd" ;;debug_watch "$file" strange_case.txt
盖尔哈2015年

geirha建议编辑的代码。
lepe

2

按照NES的说法,bash中设置了设置标志以允许调试。

set -x标志可以被设置和取消无论是从终端,或者从你的脚本中。使用+-

#!/bin/bash
#fileinfo
ls -l $1
set -x      # start debugging here
wc -l $1
set +x      # stop debugging here
file $1
set -v      # start verbose output
w | more    
echo ""
echo -n "Number of users: "
set +v      # end verbose output
who | wc -l

这是set命令的作用:

  • set -f 禁用使用元字符生成文件名。
  • set -v 在读取时打印(详细)shell输入行。
  • set -x 在执行命令之前打印命令跟踪。

set实际上具有许多功能,但是由于它是内置的shell,可悲的是没有手册页。设置手册在GNU Bash文档中

有许多命令行工具可以帮助您获取有关程序的详细信息,例如:

  • stat 显示文件或文件系统状态
  • file 确定文件类型。
  • hexdump 筛选器,以各种格式显示指定的文件
  • nohup 运行不会挂起的脚本

    和其他许多人。我试图考虑显示隐藏字符的命令,但现在无法执行。Hexdump可以做到,但是有一个更好的选择。

key命令ctrl\将导致正在运行的程序或脚本发生核心转储。然后,您可以分析核心转储。我可能会使用gdb分析coredump,但是为此存在许多程序。

bash shell也有一些漂亮的调试选项。options --debugger-v冗长的选项--dump-strings和其他漂亮的选项可以为您提供帮助。使用检查它们man bash

trap命令(内置的shell)可能对您很有帮助。陷阱表示如果程序意外退出,请执行一些操作。您可以在此处阅读有关陷阱和其他方便的Bash Shell内置函数的信息

目前来讲,调试在任何语言中都是一个巨大的话题。其他可以方便地以任何编程语言进行调试的主题包括:shell重定向和信号处理。

最后,我意识到我使用的示例很简单,但是某些shell脚本可能需要数百行。在这种情况下,我想插入注释标签并阻止我怀疑有问题的代码,或者插入退出命令,并尝试使用分治法将功能代码与损坏的代码隔离开。


1

用于调试bash脚本的GUI选项是带有BashEclipse / Shelled插件的Eclipse IDE。

这提供了您问题(breakpoints and stuff)的功能,以及用于调试复杂的bash脚本的许多其他功能。

其中一些功能包括:
https://unix.stackexchange.com/questions/155551/how-to-debug-a-bash-script

  • 断点切换
  • 单步操作
  • 步入,步出,步入功能和子例程
  • 在脚本运行时随时检查代码变量
  • TODO任务清单
  • 书签清单
  • 多窗口编辑
  • 远程共享项目环境

脚本编辑器透视图: Eclipse脚本IDE

调试透视图: Eclipse脚本调试透视图

使用的步骤是将ShelledBashEclipse插件添加到eclipse中。然后运行BashEclipse自述文本文件中提供的过程以启动调试器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.