如何在Bash中通过按键停止树莓派视频流传输管道?
解决管道中无法检测按键输入的问题
你的问题核心在于管道的标准输入(stdin)继承逻辑:
原脚本里,管道最后一段的{ while ...; }子进程,它的stdin被前一个nc命令的输出接管了,而非你的终端设备。当nc没有输出(比如还没有客户端连接拉流)时,read -rsn1会一直阻塞,导致while循环仅执行一次(输出一次"test")就停住,根本无法捕获你按下的按键。
以下是两种可行的解决思路:
方案一:后台运行推流,前台监听按键
把推流管道放到后台,让前台进程直接处理终端输入,确保read能获取到键盘操作:
#!/bin/bash WIDTH=1280 HEIGHT=720 FRAMERATE=30 SERVER_PORT=8111 STOP_KEY="p" # 启动推流管道并后台运行,记录进程PID libcamera-vid -n -t 0 --inline -o - --width $WIDTH --height $HEIGHT --framerate $FRAMERATE --libav-format h264 | nc -l -p $SERVER_PORT & STREAM_PID=$! # 前台循环监听按键 while true; do echo "Press '$STOP_KEY' to stop streaming..." read -rsn1 keypress if [ "$keypress" == "$STOP_KEY" ]; then echo "Stopping pipeline" # 杀死推流进程,避免残留子进程 kill -INT $STREAM_PID pkill -INT -f "libcamera-vid" pkill -INT -f "nc -l -p $SERVER_PORT" exit 0 fi done
方案二:强制read从终端读取
如果想保留管道结构,可以让read直接从终端设备/dev/tty读取输入,绕过管道的stdin限制:
#!/bin/bash WIDTH=1280 HEIGHT=720 FRAMERATE=30 SERVER_PORT=8111 STOP_KEY="p" # 启动推流管道后台运行 libcamera-vid -n -t 0 --inline -o - --width $WIDTH --height $HEIGHT --framerate $FRAMERATE --libav-format h264 | nc -l -p $SERVER_PORT & STREAM_PID=$! # 循环监听终端按键 while true; do echo "test" # 指定从终端读取按键输入 read -rsn1 keypress < /dev/tty if [ "$keypress" == "$STOP_KEY" ]; then echo "Stopping pipeline" kill -INT $STREAM_PID pkill -INT -f "libcamera-vid" pkill -INT -f "nc -l -p $SERVER_PORT" exit 0 fi done & # 等待推流进程结束,避免脚本直接退出 wait $STREAM_PID
补充说明
- 使用MobaXterm远程连接时,确保是交互式终端(默认ssh连接均为交互式,无需额外设置),非交互式终端下
read无法读取按键。 - 用
kill -INT发送中断信号,和手动按Ctrl+C的效果一致,能让libcamera-vid和nc优雅退出,避免残留进程占用资源。
内容的提问来源于stack exchange,提问作者Pedro
相关产品推荐
相关产品推荐

