正在运行的bash脚本挂在某处。我可以找出它在哪条线上吗?

时间:2011-01-09 18:03:43

标签: linux debugging bash

E.g。 bash调试器是否支持附加到现有进程并检查当前状态?

或者我可以通过查看/ proc中的bash进程条目轻松找到答案吗?是否有方便的工具在活动文件中提供行号?

我不想杀死并重启这个过程。

这是在Linux上 - Ubuntu 10.04。

4 个答案:

答案 0 :(得分:14)

我最近发现自己处于类似的位置。我有一个shell脚本无法通过其他方式识别(如参数等)

有很多方法可以找到关于正在运行的流程的更多信息。

使用lsof -p $pid查看哪些文件已打开,这可能会为您提供一些线索。请注意,某些文件虽然“已删除”,但仍可由脚本保持打开状态。只要脚本没有关闭文件,它仍然可以从中读取和写入 - 文件仍占用文件系统的空间。

使用strace主动跟踪脚本使用的系统调用。该脚本将读取脚本文件,因此您可以在执行前查看一些命令。使用以下命令查找read命令:

strace -p $pid -s 1024

这使得命令打印字符串的长度最多为1024个字符(通常,strace命令会截断字符串比这短得多)。

检查目录/proc/$pid以查看有关脚本的详细信息;特别注意,请参阅/proc/$pid/environ,它将为您提供由空值分隔的进程环境。要正确读取此“文件”,请使用以下命令:

xargs -0 -i{} < /proc/$pid/environ

您可以将其传输到less或将其保存在文件中。还有/proc/$pid/cmdline,但这可能只会为您提供shell名称(例如-bash)。

答案 1 :(得分:10)

没有真正的解决方案。但在大多数情况下,脚本正在等待子进程终止:

ps --ppid  $(pidof yourscript)

您还可以在shell skript中设置信号处理程序切换命令的打印:

#!/bin/bash

trap "set -x" SIGUSR1
trap "set +x" SIGUSR2

while true; do
    sleep 1
done

然后使用

kill -USR1 $(pidof yourscript)
kill -USR2 $(pidof yourscript)

答案 2 :(得分:4)

使用pstree显示脚本调用的linux命令/可执行文件。例如,21156是我悬挂脚本的pid:

ocfs2cts1:~ # pstree -pl 21156
activate_discon(21156)───mpirun(15146)─┬─fillup_contig_b(15149)───sudo(15231)───chmod(15232)
                                       ├─ssh(15148)
                                       └─{mpirun}(15147)

所以,我知道它挂在chmod命令。然后,通过以下方式显示堆栈跟踪:

ocfs2cts1:~ # cat /proc/15232/stack 
[<ffffffffa05377ef>] __ocfs2_cluster_lock.isra.39+0x1bf/0x620 [ocfs2]
[<ffffffffa053856d>] ocfs2_inode_lock_full_nested+0x12d/0x840 [ocfs2]
[<ffffffffa0538dbb>] ocfs2_inode_lock_atime+0xcb/0x170 [ocfs2]
[<ffffffffa0531e61>] ocfs2_readdir+0x41/0x1b0 [ocfs2]
[<ffffffff8120d03c>] iterate_dir+0x9c/0x110
[<ffffffff8120d453>] SyS_getdents+0x83/0xf0
[<ffffffff815e126e>] entry_SYSCALL_64_fastpath+0x12/0x6d
[<ffffffffffffffff>] 0xffffffffffffffff

哦,伙计,这可能是一个僵局......

答案 3 :(得分:1)

我结合了这个帖子中的几个答案。

  • 首先你需要确定进程 id,假设 script_which_hangs.sh 脚本挂起,只需通过脚本/进程的名称等过滤 ps
> ps -ef | grep script_which_hangs
sos      1464260 1349476  0 14:08 ?        00:00:00 bash /repo/scripts/script_which_hangs.sh
sos      1464652 1316191  0 14:08 pts/4    00:00:00 grep --color=auto script_which_hangs
  • 然后我从上面的输出中得到它的 PID 1464260
DPID=1464260; pstree -pal ${DPID}; lsof -p ${DPID}; pstree -pl ${DPID}
  • 第一个 pstree 显示包含所有参数的树(输出很长),
  • 然后 lsof 显示打开的文件,
  • 和最后一个 pstree 打印树,但没有参数,因此它更易于快速概览情况

然后查看输出,再次/再次执行以查看是否有任何更改。可能它可能会针对当前 CPU/MEM 的某些方法进行扩展,但我没有寻找过任何类似的命令。

pstree 也有 -s 参数用于包括父母,但它没有用