linux中如何后台运行一个命令并获取它的进程号
如果你只是想简单的后台挂起一个程序你可以在命令的末尾加一个&
,并紧跟&!
获取linux执行器最后一个操作返回的进程id即可,如下
your_command &
echo $!
不过上面这种使用方式,只能说是随手图方便用来做后台执行,因为它传统的用法,其实是用来配合wait
命令等待多个后台进程执行结束用的,如下
#!/bin/bash
# 启动一个后台进程(比如sleep 5)
sleep 5 &
# 获取最后一个后台进程的PID
last_pid=$!
# 输出这个PID
echo "最后一个后台进程的PID是: $last_pid"
# 等待这个特定的后台进程完成
wait $last_pid
# 输出完成信息
echo "后台进程已完成"
而如果,你是在写一个日常用的脚本,建议你使用nohup、ps、pgrep
相互配合,nohup才是正常用来后台执行命令的方法,它可以让进程生命周期不终止于本次客户端连接,但是它会忽略执行器返回的进程id,因此无法用$!
获取id,需要ps或者pgrep解析结果,并且通常情况下后台进程会有多个,也不会用$!
一个个的获取,那多累,命令如下
#例如有一个脚本后台启动了一个叫做test的进程
/opt/test.sh &
#如果你希望在前台输出准确进程id就用ps直接解析
ps -aux | grep HiveMetaStore | grep -v grep | awk '{print $2}'
#但是!!!awk的结果不能在管道中直接写入文件,执行会有问题,所以你可以用pgrep
pgrep -f test > /opt/out
使用ps -aux
或者ps -ef
在获取进程id上都可以,参数的区别是其他细节输出不同而已,但是要注意的是pgrep -f
命令输出的进程条数很可能会有多条,这是因为-f
做模糊匹配的时候,会把所有有关键字的进程全部搜索出来,所以它的结果里面会有grep本身的进程号等,如果你需要精确的进程号就要用ps进一步解析了,比如如下脚本
#!/bin/bash
tmp=""
#使用 $() 和 拼接结果字符串 的方式找到所有需要的进程id
tmp=$(ps -aux | grep metastore | grep -v grep | awk '{print $2}')
#分割两个命令的结果
tmp+=" "
tmp+=$(ps -aux | grep hiveserver2 | grep -v grep | awk '{print $2}')
#将进程id拆成数组
readarray -t ADDR <<< "$(echo "$tmp" | tr ' ' '\n')"
tmp=""
#遍历数组kill进程
for ids in "${ADDR[@]}"; do
kill -9 "$ids"
echo "kill run-id by $ids"
done