E.g。 bash调试器是否支持附加到现有进程并检查当前状态?
或者我可以通过查看/ proc中的bash进程条目轻松找到答案吗?是否有方便的工具在活动文件中提供行号?
我不想杀死并重启这个过程。
这是在Linux上 - Ubuntu 10.04。
答案 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)
我结合了这个帖子中的几个答案。
> 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
DPID=1464260; pstree -pal ${DPID}; lsof -p ${DPID}; pstree -pl ${DPID}
然后查看输出,再次/再次执行以查看是否有任何更改。可能它可能会针对当前 CPU/MEM 的某些方法进行扩展,但我没有寻找过任何类似的命令。
pstree 也有 -s 参数用于包括父母,但它没有用