我有一个在Ubuntu上运行的bash脚本。
现在是否有可能在不重新启动脚本的情况下查看当前执行的行/命令?
问题在于脚本有时永远不会退出。这真的很难复制(现在我抓住了它),所以我不能停止脚本并开始调试。
任何帮助都将不胜感激。
P.S. 脚本逻辑很难理解,所以我无法通过思考弄清楚为什么它被冻结了。
尝试找出 shell 的进程 ID(pid),可以使用 ps -ef | grep <script_name>
命令。
将此 pid 存储到 shell 变量 $PID
中。
通过以下命令查找所有子进程:ps --ppid $PID
ps --ppid $PID
如果您发现一个或多个命令没有响应(例如,它被卡在一系列管道命令中),请尝试多次重复执行该命令。如果命令不改变,则说明脚本卡在某个命令中。此时,您可以将跟踪命令附加到正在运行的子进程:
sudo strace -p $PID
这将展示正在执行的内容,是无限循环(例如从管道读取),还是等待永远不会发生的某些事件。
如果您发现ps --ppid $PID
在变化,则表示您的脚本正在前进,但卡在某个地方,例如在脚本中的本地循环。从更改的命令中,可以给您一个提示,在脚本的哪个部分它正在循环。
code
sudo strace -p $PID code
产生了 code
read(3, code
。数字是文件描述符,在使用 lsof 命令后我发现它是 Unix 套接字。因此,脚本调用某些系统操作并等待通过该套接字收到响应。不幸的是,这还不够。 - longcat /proc/${PID}/fdinfo/3
的输出吗? - hesham_EE
set -x
, 但这需要重新启动它。我唯一能想到的建议是使用strace
,但我不知道将其输出转换为脚本行有多容易。 - Barmar/dev/null
的内容,全局替换/dev/null
为可写文件(但会得到大量垃圾),或者使用gdb
和Bash进程的dup2
系统调用将/dev/null
的fd更改为另一个文件。这不会精确地告诉你正在处理哪一行,但很有可能命令的大部分输出都被发送到那里,因此它可能会给你一些提示。 - damienfrancois