手动执行正常的SIGINT超时终止命令,转为脚本后无输出求助
问题描述
我用以下命令序列在bash终端逐条执行时完全正常,temp.dat能得到需要的内容,但写到bash脚本里运行时,temp.dat是空的:
echo <some_input> | <some_command> > temp.dat & pid=$! sleep 5 kill -INT "$pid"
这么写的原因:
<some_command>需要输入,所以用管道传<some_input>- 要把命令输出保存到单独文件,所以做了输出重定向
- 希望过段时间用SIGINT终止该命令
试过在脚本首行写#!/bin/bash -i运行交互式shell,没用。
更新:<some_command>是调用Python脚本,一开始以为不影响,但后来确认就是Python脚本导致的差异。
解决方案
原因分析
Python默认会对标准输出做缓冲:在终端交互式环境下是行缓冲,输出会实时写入文件;但在脚本非交互式环境下是块缓冲,收到SIGINT时缓冲内的内容还没写入磁盘,就导致temp.dat为空。
具体解决方法
让Python脚本禁用缓冲
运行Python脚本时加-u参数,强制标准输出无缓冲:echo <some_input> | python -u your_script.py > temp.dat & pid=$! sleep 5 kill -INT "$pid"也可以在Python脚本内手动控制缓冲:
import sys # 每次输出后手动刷新缓冲 print("内容", flush=True) # 或者直接设置标准输出为无缓冲模式 sys.stdout = open(sys.stdout.fileno(), 'w', buffering=0)用
stdbuf强制无缓冲
不修改Python脚本的话,可在bash中用stdbuf命令控制输出缓冲:echo <some_input> | stdbuf -o0 <some_command> > temp.dat & pid=$! sleep 5 kill -INT "$pid"-o0表示让标准输出完全无缓冲。改用输入文件替代管道
把输入内容写入临时文件,让Python脚本读取该文件,避免管道带来的缓冲问题:echo <some_input> > input.tmp <some_command> < input.tmp > temp.dat & pid=$! sleep 5 kill -INT "$pid" rm input.tmp
内容的提问来源于stack exchange,提问作者sgalpha01
相关产品推荐
相关产品推荐

