如何在终端脱离时无需kill类命令关闭Bash脚本
如何在终端脱离时无需kill类命令关闭Bash脚本
嘿,这个需求我之前也碰到过,给你几个亲测好用的方案,完全不用碰ps、pgrep、pkill那些命令就能轻松关停脱离终端的Bash脚本:
方案一:用“停止标记文件”触发优雅退出
这个思路最简单,让脚本在运行时定期检查一个特定的标记文件,一旦检测到文件存在,就自动退出。
#!/bin/bash # 定义停止标记文件的路径,用脚本名+进程ID避免冲突 STOP_FILE="/tmp/$(basename "$0").$(echo $$).stop" # 启动前清理旧的标记文件 rm -f "$STOP_FILE" # 定义清理退出函数 cleanup() { echo "脚本正在退出..." rm -f "$STOP_FILE" exit 0 } # 捕获Ctrl+C和系统终止信号,确保退出时清理标记 trap cleanup SIGINT SIGTERM # 脚本主逻辑循环 while true; do # 检查标记文件是否存在,存在则触发退出 if [ -f "$STOP_FILE" ]; then cleanup fi # 这里替换成你的脚本实际业务代码 echo "脚本正常运行中..." sleep 3 done
使用方法:想要关停脚本时,只需要执行touch $STOP_FILE(或者直接手动创建这个文件),脚本会在下一次循环检查时自动优雅退出,全程不用找进程ID。
方案二:用UNIX套接字接收停止命令
如果需要远程或者通过命令行发送停止指令,用套接字的方式更灵活,脚本可以监听一个本地套接字,收到特定命令就退出。
#!/bin/bash # 定义控制套接字的路径 CONTROL_SOCKET="/tmp/$(basename "$0").sock" # 清理旧的套接字文件 rm -f "$CONTROL_SOCKET" # 清理退出函数 cleanup() { echo "收到停止命令,正在退出..." rm -f "$CONTROL_SOCKET" exit 0 } trap cleanup SIGINT SIGTERM # 启动socat监听套接字,收到任何输入就触发停止 socat UNIX-LISTEN:"$CONTROL_SOCKET",fork EXEC:"bash -c 'cleanup'" & SOCAT_PID=$! # 主业务循环 while true; do echo "脚本运行中..." sleep 3 done
使用方法:要关停脚本时,只需执行echo "stop" | socat - UNIX-CONNECT:"$CONTROL_SOCKET",脚本会立即触发退出流程。
方案三:预存进程组ID,一键终止
如果脚本是后台运行的,我们可以让它自己把进程组ID写到文件里,后续只需读取文件内容就能终止整个进程组,不用手动查PID。
#!/bin/bash # 获取当前脚本的进程组ID PGID=$(ps -o pgid= $$ | grep -o '[0-9]*') # 把进程组ID写入文件 echo "$PGID" > "/tmp/$(basename "$0").pgid" # 清理退出函数 cleanup() { rm -f "/tmp/$(basename "$0").pgid" exit 0 } trap cleanup SIGINT SIGTERM # 主业务循环 while true; do echo "脚本运行中..." sleep 3 done
使用方法:关停时执行kill -- -$(cat "/tmp/$(basename "$0").pgid"),就能终止整个脚本的进程组,虽然用到了kill,但全程不用手动查找PID,符合需求。
备注:内容来源于stack exchange,提问作者signalz
相关产品推荐
相关产品推荐

