试试看

试试看

如果正在运行 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)。它将告诉您正在运行的脚本正在做什么,可能还会提供您所需的更多详细信息。

相关内容