向Screen发送命令时stuff的限制与换行符异常问题如何解决?
向Screen会话传递长命令的实现方案
原有短命令方案
之前传递较短的bash命令时,使用stuff选项可以正常执行,示例如下:
screen -d -m -S worker screen -S worker -X -p 0 stuff $'/usr/bin/env python3 /root/worker.py\n'
遇到的问题
需要从本地文件读取长命令传入Screen会话时出现异常:即使在文件末尾追加\n,$()结构也会自动吞掉换行符。尝试过printf、修改IFS变量等多种方案,要么无法保留换行符,要么保留换行后命令无法正常传入Screen会话。
错误尝试示例:
GEO_COMMAND=/foo/geo_command.txt screen -S worker -X -p 0 stuff printf '%\n' "$GEO_COMMAND" # 或者 screen -S worker -X -p 0 stuff $GEO_COMMAND
本次待传递的命令文件内容总长度超过160字符,格式类似:foo -bar -geo1 -geo2 -blah -keys ......; /root/finish_job.sh
问题根因
Screen的stuff选项本身不支持传入大型长命令,且对换行符的格式要求极为严格,常规处理换行的方案适配性很差。
最终解决方案
采用readreg+paste的组合方案替代stuff实现长命令传递:
- 先用
readreg命令将存储命令的文本文件内容读取到Screen的寄存器中 - 再用
paste命令将寄存器中的内容传递到目标Screen会话
具体实现代码示例:
# 定义命令文件路径与会话名 COMMAND_FILE=/foo/geo_command.txt SCREEN_NAME=worker # 将命令文件内容读入名为c的自定义寄存器 screen -S $SCREEN_NAME -X readreg c $COMMAND_FILE # 将寄存器内容粘贴到Screen的0号窗口 screen -S $SCREEN_NAME -X -p 0 paste c # 追加换行触发命令执行 screen -S $SCREEN_NAME -X -p 0 stuff $'\n'
该方案优势:
- 不需要提前在命令文件末尾添加换行符
- 不需要为文件内的命令额外添加转义引号
- 天然支持文件内写入多条连续命令(用
;分隔的多段执行逻辑)
内容的提问来源于stack exchange,提问作者Todd Curry
相关产品推荐
相关产品推荐

