Linux系统中常常需要获取进程的pid进行一些操作,而Linux 的交互式 Shell 与 Shell 脚本存在一定的差异,主要是由于后者存在一个独立的运行进程,因此在获取进程 pid 上二者也有所区别。
ps 命令
ps
命令是最常用的Linux命令之一,用于获取当前系统中的进程信息,ps
是显示瞬间进程的状态,并不动态连续;如果想对进程进行实时监控应该用top
命令。
ps
命令的参数非常多,这个可以自己找资料查看,最常用的就是ps -ef
或者ps -aux
了。
ps -aux
表示显示所有包含其他使用者的行程,一般能够获取到比较详细的进程信息了,ps -ef
也表示显示所有进程信息,连同命令行。因此如果想查找一个进程,通常这两个命令就比较全面了。
交互式 Shell 获取 pid
在ps命令的基础上,如果我们知道进程的name,那么可以利用grep
来获取其pid(需要通过-v来过滤掉grep本身),并通过awk
显示出来。
ps -ef | grep "name" | grep -v grep | awk '{print $2}'
或者直接使用awk
ps -ef | awk '/[n]ame/{print $2}'
这里名称首字母加[]
的目的是为了避免匹配到awk
自身的进程。
当然,Linux系统也支持直接查找:
- 最简单的方法是使用
pgrep
:
`pgrep -f name`
- 如果需要查找到 pid 之后
kill
掉该进程,还可以使用pkill
:
`pkill -f name`
- 如果是可执行程序的话,可以直接使用
pidof
:
`pidof name`
Bash Shell 脚本获取进程 pid
在使用 Shell 脚本获取进程 pid 时,如果直接使用上述命令,可能会出现多个 pid 结果,例如:
代码语言:txt复制#! /bin/bash
# process-monitor.sh
process=$1
pid=$(ps x | grep $process | grep -v grep | awk '{print $1}')
echo $pid
执行 process-monitor.sh 会出现多个结果:
代码语言:txt复制$> sh process-monitor.sh
3036 3098 3099
进一步排查可以发现,多出来的几个进程实际上是子 Shell 的(临时)进程:
代码语言:txt复制root 3036 2905 0 09:03 pts/1 00:00:45 /usr/java/jdk1.7.0_71/bin/java ...name
root 4522 2905 0 16:12 pts/1 00:00:00 sh process-monitor.sh name
root 4523 4522 0 16:12 pts/1 00:00:00 sh process-monitor.sh name
对于这种情况,我们也只能加入更多的grep条件来做进一步的判断了
如果我们不确定找到的进程是否正确,可以通过判断pid所在的进程是否运行:
代码语言:txt复制if ps -p $PID > /dev/null
then
echo "$PID is running"
# Do something knowing the pid exists, i.e. the process with $PID is running
fi
/dev/null
是Linux中的一个特殊输出位置。
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!