You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bash脚本中正确查找、停止并重启树莓派上的Motion进程?

解决Bash脚本终止Motion进程后自身退出的问题

问题根源

你遇到的问题是因为pgrep -f motion会匹配所有命令行包含"motion"字符串的进程,包括当前正在运行的这个脚本(脚本内容里有motion相关命令,进程列表中会显示脚本的执行路径及相关内容)。执行kill时会把脚本自身的PID也杀掉,导致脚本直接终止,后续的sleep、echo和重启命令都无法执行。

正确的实现方法

方法1:精确匹配进程名(推荐)

使用pgrep -x motion,-x参数表示精确匹配进程名,只查找进程名严格等于motion的进程,不会匹配脚本自身:

#!/bin/bash
# 查找并重启motion进程
MOTION_PID=$(pgrep -x motion)
# 先判断进程是否存在,避免kill空值报错
if [ -n "$MOTION_PID" ]; then
    sudo kill "$MOTION_PID"
    sleep 5
fi
echo "restarting"
sudo motion -b -c ~/.motion/motion.conf

方法2:排除脚本自身PID

如果必须使用-f参数(比如需要匹配带特定参数的motion进程),可以通过$$(当前脚本的PID)过滤掉自身:

#!/bin/bash
# 查找并重启motion进程
# 获取所有含motion的PID,排除当前脚本PID
MOTION_PIDS=$(pgrep -f motion | grep -v $$)
if [ -n "$MOTION_PIDS" ]; then
    sudo kill $MOTION_PIDS
    sleep 5
fi
echo "restarting"
sudo motion -b -c ~/.motion/motion.conf

方法3:使用pidof命令

pidof默认只匹配进程名,效果和pgrep -x一致:

#!/bin/bash
# 查找并重启motion进程
MOTION_PID=$(pidof motion)
if [ -n "$MOTION_PID" ]; then
    sudo kill "$MOTION_PID"
    sleep 5
fi
echo "restarting"
sudo motion -b -c ~/.motion/motion.conf

额外优化

如果kill后需要确保进程完全退出,可以改用kill -TERM(默认就是TERM信号),或者等待进程退出后再执行重启:

#!/bin/bash
MOTION_PID=$(pgrep -x motion)
if [ -n "$MOTION_PID" ]; then
    sudo kill "$MOTION_PID"
    # 等待进程退出,最多等10秒
    for i in {1..10}; do
        if ! pgrep -x motion > /dev/null; then
            break
        fi
        sleep 1
    done
fi
echo "restarting"
sudo motion -b -c ~/.motion/motion.conf

内容的提问来源于stack exchange,提问作者NigelS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:22:21