如果正在运行 bash 脚本,它将在我的ps
输出中显示为
# ps -e
[...]
10043 pts/1 00:00:00 bash
[...]
我如何才能知道正在执行的精确命令?
谢谢你,
答案1
据我所知,从局外人的角度来看,没有很好的方法可以查看 Bash 解释器内部运行的精确命令。不过,有几件事你可以做,以了解有关运行过程的更多信息。
- 使用
strace(1)
以 root 用户身份连接到进程 ID 并打印进程正在进行的系统调用。您可以strace
使用选项限制输出的范围-e
。例如,要仅查看通常类似于stdout
脚本的写入操作,请运行:strace -p 10043 -s99999 -e write
- 使用
/proc
文件系统来了解有关进程的更多信息。例如,对于 PID,10043
您可以cd /proc/10043
。它将包含有趣的文件,例如:environ
文件 - 包含正在运行的进程的环境。要查看设置变量,您可以运行:tr '\0' '\n' < ./environ
cmdline
文件 - 将准确显示正在运行的进程的命令行参数。您可以按如下方式查看这些参数:tr '\0' ' ' < /proc/19774/cmdline | sed 's/ $/\n/'
。ps(1)
命令也会显示类似这样的信息ps -up 19774
。fd
文件夹 - 包含正在运行的进程的打开文件句柄。要查看进程打开的文件,您可以ls -l ./fd/
。lsof(8)
命令也会显示此类信息。对于 bash 脚本,文件描述符255
通常包含正在运行的脚本(即/proc/19774/fd/255
)。情况并非总是如此。
- 使用
pstree(1)
查看进程及其子进程,以了解脚本内执行的位置。例如pstree -ap 10043
试试看
创建一个/tmp/daemonwait
包含以下内容:
cat > /tmp/daemonwait <<'EOF'
while sleep 1;do echo hello;done
EOF
以普通用户身份运行该脚本。
bash /tmp/daemonwait > /dev/null &
#save the PID for later use
pid=$!
因为您以用户身份启动了该进程,所以您可以读取/proc
该进程的文件系统。
以下是上述描述中的一些可供尝试的示例。
#view the running bash script; press q for quit
less /proc/$pid/fd/255
#view the environment of the running bash script
tr '\0' '\n' < /proc/$pid/environ | less
#watch the process write to stdout or stderr; requires root
sudo strace -p $pid -s99999 -e write
#list the process, child processes, and their args
pstree -ap $pid
当脚本不是文件描述符 255 时
探索文件描述符255
不是正在运行的脚本的情况。
#view all open files of the process
ls -l /proc/$pid/fd/
#notice the daemonwait script is file descriptor 255
现在让我们将其daemonwait
视为可执行脚本。注意:如果您不使用 bash 作为默认 shell,则需要将其添加#!/bin/bash
到脚本的开头/tmp/daemonwait
。
kill $pid
chmod 755 /tmp/daemonwait
/tmp/daemonwait > /dev/null &
pid=$!
让我们再次看一下正在运行的进程的文件描述符。
ls -l /proc/$pid/fd/
#notice the daemonwait script is now file descriptor 254
清理
玩完后请清理一下。
kill $pid
rm /tmp/daemonwait
答案2
选项 1:使用 启动脚本bash -x /path/to/your/script.sh
。然后 Bash 将打印出正在执行的每一行,并以 + 为前缀。
选项 2:使用斯特拉斯:(strace -p 10043
将 10043 替换为该脚本的实际进程 ID)。它将告诉您正在运行的脚本正在做什么,可能还会提供您所需的更多详细信息。