Linux命令-pidof(查找指定进程名称的进程号)
Linux命令-pidof查找指定进程名称的进程号pidof命令用于根据进程名称查找对应的进程 IDPID。它是一个轻量级的进程查找工具直接返回进程号非常适合在 Shell 脚本中使用。#### 基本语法bashpidof [选项] 进程名称#### 常用选项| 选项 | 说明 ||------|------||-s| 只返回单个 PIDSingle shot即使有多个同名进程也只返回一个 ||-c| 只返回在同一根目录下运行的进程 PID仅限 root 用户使用 ||-x| 同时查找脚本本身Shell、Perl、Python 等脚本的进程名 ||-o omitpid| 忽略指定 PID排除自身或特定进程 ||-d sep| 指定多个 PID 之间的分隔符默认空格 ||-n| 配合-o使用跳过最近的 N 个新进程 |发行版差异不同发行版的pidof选项可能不同。CentOS/RHEL 使用的pidof来自sysvinit-tools包选项集合与 Debian/Ubuntu 的pidof来自psmisc或procps略有差异。#### 核心用法示例1.查找进程 PIDbash pidof sshd # 查找 sshd 服务的 PID # 输出845 1230 5678 可能返回多个 PIDSSH 为每个连接创建子进程2.只获取单个 PID用于脚本bash pidof -s nginx # 只返回一个 nginx 进程 PID # 输出12343.以逗号分隔输出多个 PIDbash pidof -d , httpd # 多个 PID 用逗号分隔 # 输出1234,5678,90124.排除当前 Shell 脚本自身bash # 在脚本中使用时排除自身进程 pidof -x -o $$ myscript.sh5.查找正在运行的 Shell 脚本bash pidof -x backup.sh # 查找运行中的 backup.sh 脚本进程 # 不加 -x 只能查找二进制程序的 PID脚本需要 -x 参数#### 进程查找全流程##### 1. 确认进程是否运行bash# 检查 nginx 是否在运行if pidof nginx /dev/null 21; then echo nginx 正在运行else echo nginx 未运行fi##### 2. 获取精确的进程信息bash# 先获取 PIDnginx_pid$(pidof -s nginx)# 再用 ps 查看详细信息ps -p $nginx_pid -o pid,ppid,user,cmd,%mem,%cpu# 或者一行搞定ps -p $(pidof -s nginx) -o pid,ppid,user,cmd##### 3. 获取所有匹配进程的详细信息bash# 获取所有 ssh 相关进程for pid in $(pidof sshd); do echo --- PID: $pid --- ps -p $pid -o pid,user,%cpu,%mem,cmd --no-headersdone##### 4. 与 pgrep 配合使用bash# pidof 按精确名称查找pidof python3# 输出1234 5678# pgrep 按模糊匹配查找更灵活pgrep -f python3# 输出1234 5678 9012# 结合使用先 pidof 精确匹配再 pgrep 模糊补充all_pids$({ pidof python3; pgrep -f python3.*script ; } | sort -u)#### 与同类命令对比| 命令 | 用途 | 匹配方式 | 输出格式 ||------|------|---------|---------||pidof| 按精确名称查找 PID | 精确匹配进程名 | 空格分隔的 PID 列表 ||pgrep| 按模式查找 PID | 正则表达式匹配 | 换行分隔的 PID 列表 ||ps -C name| 按进程名查找 | 精确匹配进程名 | 完整进程信息 ||ps aux \| grep name| 通用进程搜索 | 模糊匹配 | 完整进程信息含 grep 自身 ||pidof -x| 查找脚本 PID | 精确匹配含脚本 | 空格分隔的 PID 列表 |##### 详细对比示例bash# pidof简洁精确匹配pidof bash# 输出234 567 890# pgrep支持正则功能更强pgrep -u root bash # 只找 root 用户的 bashpgrep -l bash # 显示进程名和 PIDpgrep -f /usr/bin/python # 匹配完整命令行# ps -C精确匹配 完整信息ps -C bash -o pid,user,%cpu,%mem,cmd# ps aux | grep最灵活但需要过滤 grep 自身ps aux | grep [b]ash # 巧用 [] 避免匹配到 grep 自身#### ⚠️ 重要注意事项1.进程名称长度限制Linux 系统中进程名称最多 15 个字符/proc/pid/comm。pidof基于此进行匹配bash # 如果进程名超过 15 个字符使用完整命令行匹配 pidof my-very-long-process-name # 可能找不到 pgrep -f my-very-long-process # 用 pgrep 代替2.区分大小写pidof是精确区分大小写的bash pidof Nginx # 找不到如果实际进程名是 nginx pidof nginx # 正确3.多实例场景一个程序可能启动多个进程如每个 SSH 连接一个 sshd 子进程bash pidof sshd # 可能返回845 1230 4567 8912 # 其中 845 是主进程其余是子进程4.脚本自身排除在脚本中使用pidof时务必排除自身bash #!/bin/bash # 错误会包含自己 count$(pidof -x $(basename $0) | wc -w) # 正确排除自身的 PID count$(pidof -x -o $$ $(basename $0) | wc -w)5.僵尸进程pidof可能返回僵尸进程的 PID需要额外判断bash pid$(pidof -s process_name) if [ -n $pid ]; then state$(ps -p $pid -o stat) if [[ $state ~ Z ]]; then echo 进程 $pid 是僵尸进程 fi fi#### 实用场景##### 1. 服务健康检查脚本bash#!/bin/bash# 检查关键服务是否运行check_service() { local service$1 if pidof $service /dev/null 21; then echo [✓] $service 正在运行 (PID: $(pidof -s $service)) return 0 else echo [✗] $service 未运行! return 1 fi}# 检查多个关键服务check_service nginxcheck_service sshdcheck_service mysqldcheck_service docker##### 2. 进程自动重启监控bash#!/bin/bash# 监控进程异常退出时自动重启PROCESSmyappRESTART_CMD/usr/local/bin/myapp --daemonwhile true; do if ! pidof $PROCESS /dev/null 21; then echo $(date): $PROCESS 未运行正在重启... $RESTART_CMD sleep 5 if pidof $PROCESS /dev/null 21; then echo $(date): 重启成功 (PID: $(pidof -s $PROCESS)) else echo $(date): 重启失败请检查! fi fi sleep 10done##### 3. 优雅关闭进程bash#!/bin/bash# 先尝试 SIGTERM 优雅关闭超时后 SIGKILLPROCESSjavapid$(pidof -s $PROCESS)if [ -z $pid ]; then echo $PROCESS 未运行 exit 0fiecho 正在关闭 $PROCESS (PID: $pid)...# 发送 SIGTERMkill $pid# 等待最多 30 秒for i in $(seq 1 30); do if ! pidof $PROCESS /dev/null 21; then echo $PROCESS 已优雅关闭 exit 0 fi sleep 1done# 超时强制 SIGKILLecho 超时强制关闭...kill -9 $pidsleep 1if pidof $PROCESS /dev/null 21; then echo 强制关闭失败! exit 1else echo $PROCESS 已强制关闭fi##### 4. 收集进程资源使用情况bash#!/bin/bash# 收集指定进程的 CPU 和内存使用率PROCESSnginxINTERVAL5COUNT3PID$(pidof -s $PROCESS)if [ -z $PID ]; then echo 进程 $PROCESS 未找到 exit 1fiecho 监控进程: $PROCESS (PID: $PID)echo 时间 CPU% MEM% RSS(KB)for i in $(seq 1 $COUNT); do ps -p $PID -o pid,pcpu,pmem,rss --no-headers | while read pid cpu mem rss; do echo $(date %H:%M:%S) $cpu $mem $rss done sleep $INTERVALdone##### 5. 批量操作同类型进程bash# 查看所有 Python 脚本的详细信息for pid in $(pidof -x python3); do echo PID: $pid cat /proc/$pid/cmdline | tr \0 echo echo 打开的文件数: $(ls /proc/$pid/fd 2/dev/null | wc -l) echo ---done#### 故障排除1.pidof 无输出进程未找到bash # 确认进程名拼写正确 ps aux | grep process_name # 对于脚本使用 -x 参数 pidof -x script.sh # 使用 pgrep 作为备选支持正则 pgrep -l process_name2.pidof 返回多个 PIDbash # 这是正常现象使用 -s 获取单个 PID pidof -s nginx # 或选择主进程PPID 为 1 的那个 for pid in $(pidof nginx); do ppid$(ps -o ppid -p $pid) if [ $ppid 1 ]; then echo 主进程 PID: $pid break fi done3.在脚本中使用 pidof 误包含自身bash # 错误示例 pidof -x my_monitor.sh # 会包含这个监控脚本自身 # 正确做法 pidof -x -o $$ my_monitor.sh # 排除当前脚本的 PID4.pidof 在新版本系统中行为不同bash # 检查 pidof 来源 rpm -qf $(which pidof) # CentOS/RHEL dpkg -S $(which pidof) # Debian/Ubuntu # 查看支持的所有选项 pidof --help5.特定用户进程的 PID 查找bash # pidof 本身不支持按用户过滤 # 改用 pgrep pgrep -u www-data nginx # 或结合 ps 过滤 ps -u www-data -o pid | while read pid; do if [ $(cat /proc/$pid/comm 2/dev/null) nginx ]; then echo $pid fi done#### 最佳实践1.脚本中优先使用pidof -s避免处理多个 PID 的复杂情况bash PID$(pidof -s nginx) if [ -n $PID ]; then echo nginx 在运行PID: $PID kill -HUP $PID # 重新加载配置 fi2.结合/proc文件系统获取更详细信息bash pid$(pidof -s mysqld) if [ -n $pid ]; then echo 启动时间: $(ps -p $pid -o lstart) echo 运行时长: $(ps -p $pid -o etime) echo CPU 时间: $(ps -p $pid -o time) fi3.使用-d选项便于后续处理bash # 用逗号分隔便于数组处理 pids$(pidof -d , nginx) IFS, read -ra PID_ARRAY $pids echo 共找到 ${#PID_ARRAY[]} 个 nginx 进程4.写健壮的脚本始终检查 pidof 返回值bash kill_gracefully() { local process$1 local timeout${2:-30} local pid$(pidof -s $process) if [ -z $pid ]; then return 0 # 进程不存在视为成功 fi kill $pid # ... 后续等待逻辑 }#### 实际应用示例##### 完整的进程状态报告脚本bash#!/bin/bash# 生成系统关键进程的状态报告REPORT_FILE“/tmp/process_report_$(date %Y%m%d).txtecho “ 系统进程状态报告 ” $REPORT_FILEecho “生成时间: $(date)” $REPORT_FILEecho “” $REPORT_FILE# 定义要检查的进程列表PROCESSES( “sshd:SSH 服务” “nginx:Web 服务器” “mysqld:MySQL 数据库” “docker:Docker 引擎” “cron:定时任务” “rsyslogd:系统日志”)echo “进程名称 状态 PID CPU% MEM% 运行时间” $REPORT_FILEecho “------------------------------------------------------------” REPORTFILEforentryinREPORT_FILEfor entry in REPORTFILEforentryin{PROCESSES[]}”; do proc“KaTeX parse error: Expected }, got EOF at end of input: …%:*} desc{entry##*:}” pid(pidof−s(pidof -s (pidof−sproc 2/dev/null) if [ -n “$pid” ]; then read cpu mem etime $(ps -ppid−opcpu,pmem,etime2/dev/null)cpupid -o pcpu,pmem,etime 2/dev/null) cpupid−opcpu,pmem,etime2/dev/null)cpu{cpu:-N/A}; memmem:−N/A;etime{mem:-N/A}; etimemem:−N/A;etime{etime:-N/A} printf “%-20s [运行] %-7s %-5s %-5s %-8s (%s)\n” \ “descdesc descpid” “cpucpu cpumem” “etimeetime etimeproc” REPORTFILEelseprintfREPORT_FILE else printf %-20s [停止] %-7s %-5s %-5s %-8s (%s)\n \ REPORTFILEelseprintfdesc “-” “-” “-” “-” “$proc” $REPORT_FILE fidoneecho “” $REPORT_FILEecho 报告已生成: $REPORT_FILEcat $REPORT_FILEpidof虽然功能单一但在 Shell 脚本中极其常用。它是进程管理中连接进程名和 PID 的桥梁——配合kill、ps、/proc文件系统使用可以构建出功能强大的进程监控和管理脚本。记住当你需要在脚本中找到某个进程的 PID时pidof 永远是第一选择。