You need to enable JavaScript to run this app. ash执行kill提示需指定杀除对象 读取/dev/rs232发MQTT时cat进程无法终止
优惠活动
大模型
产品
解决方案
定价
更多

ash执行kill提示需指定杀除对象 读取/dev/rs232发MQTT时cat进程无法终止

问题根源
  • 你用到的命令替换$()会等待内部命令执行完成后才返回输出结果,哪怕你在内部将cat放到后台运行,命令替换仍会阻塞等待cat进程退出,之后才会执行后续的pid=$!逻辑。此时要么cat进程已经退出、要么进程仍在阻塞读设备,$!根本无法捕获到本次cat进程的PID,导致kill的参数为空,触发ash: you need to specify whom to kill报错。
  • /dev/rs232是串口字符设备,cat默认会持续读取设备内容直到收到EOF,只要设备没有主动断开,cat进程永远不会主动退出。
可行解决方案

方案1:使用timeout命令(推荐,大部分带BusyBox的嵌入式环境都支持)

直接用timeout限制cat的运行时长,读完现有串口内容后自动终止进程,无需手动管理PID:

#!/bin/ash
while true; do
    # 0.1秒超时可根据串口波特率调整,保证读完所有缓存内容即可
    rs=$(timeout 0.1 cat /dev/rs232)
    # 非空内容才推送MQTT,避免发送无效空消息
    if [ -n "$rs" ]; then
        mosquitto_pub -h 替换为实际MQTT服务IP -m "$rs" -t rs_test/message
    fi
    # 加小延迟避免循环占满CPU
    sleep 0.2
done

方案2:无timeout时用临时文件中转

如果系统没有内置timeout命令,可以用临时文件存输出,后台运行cat后延迟手动杀进程:

#!/bin/ash
# 提前创建临时文件,避免每次循环重复生成
touch /tmp/rs232_buffer
while true; do
    cat /dev/rs232 > /tmp/rs232_buffer &
    pid=$!
    # 等待cat读完现有缓存内容
    sleep 0.1
    # 杀进程时丢弃错误输出,避免进程已经退出时的报错
    kill $pid 2>/dev/null
    rs=$(cat /tmp/rs232_buffer)
    # 清空缓存文件避免下次读取重复内容
    > /tmp/rs232_buffer
    if [ -n "$rs" ]; then
        mosquitto_pub -h 替换为实际MQTT服务IP -m "$rs" -t rs_test/message
    fi
    sleep 0.2
done

方案3:单条串口输出场景用read轻量实现

如果你的串口每次输出都是单行内容,可以直接用ash内置的read命令,无需创建额外进程:

#!/bin/ash
while true; do
    # -t参数指定读取超时时间,读到内容就返回
    if read -t 0.1 rs < /dev/rs232; then
        mosquitto_pub -h 替换为实际MQTT服务IP -m "$rs" -t rs_test/message
    fi
    sleep 0.1
done
额外说明

不要使用kill $(pgrep cat)的逻辑,会误杀系统中其他正常运行的cat进程,且无cat进程时仍会触发kill参数为空的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 14:48:04