如何在命令替换时实时显示终端命令输出并校验结果?
实时显示命令输出并捕获内容校验的解决方案
嗨,我完全懂你的困扰——用命令替换$(...)确实会把命令的所有输出先缓存起来,直到命令跑完才返回,根本看不到实时的下载进度,对长时间运行的任务来说太不友好了。不过咱们可以用tee命令来搞定这个问题,它能同时帮你实现实时输出到终端和保存输出内容做后续错误检查的需求。
修改后的可用脚本
#!/bin/bash while : do # 创建唯一的临时日志文件,避免多实例运行时互相干扰 TEMP_LOG=$(mktemp) # 执行streamlink并处理输出: # - 2>&1 把stderr重定向到stdout,确保错误信息和进度信息都能被捕获 # - tee 同时把输出实时打印到终端,还写入临时文件供后续检查 streamlink -o "$NAME" "$STREAM" best 2>&1 | tee "$TEMP_LOG" # 检查临时文件里是否包含目标错误字符串 if grep -q "No playable streams" "$TEMP_LOG"; then echo "Delaying!" sleep 15 fi # 清理临时文件,避免磁盘占用 rm "$TEMP_LOG" done
关键细节说明
2>&1:把命令的标准错误(stderr)重定向到标准输出(stdout),这样streamlink的实时进度、速度提示,以及错误信息都会走同一个输出流,不会漏掉任何需要的内容。tee "$TEMP_LOG":tee就像一个输出分流器——它会把接收到的内容同时输出到终端(让你实时看到下载状态),还会把内容写入临时文件,方便后续做错误校验。mktemp:自动生成唯一的临时文件路径,避免多个脚本进程同时运行时,日志文件被互相覆盖的问题。grep -q:直接在临时文件里搜索目标字符串,-q参数让grep只返回结果状态,不输出匹配内容,比把整个文件读进变量里更高效,尤其是输出内容很大的时候。
进阶优化(可选)
如果你不想用临时文件,也可以用bash的**协进程(coproc)**实现内存级别的捕获,避免磁盘IO:
#!/bin/bash while : do # 启动协进程,同时把输出实时打印到终端 coproc streamlink -o "$NAME" "$STREAM" best 2>&1 | tee /dev/tty # 读取协进程的输出到变量 OUT=$(cat <&"${COPROC[0]}") # 检查错误字符串 if [[ $OUT == *"No playable streams"* ]]; then echo "Delaying!" sleep 15 fi done
不过这个方案要求bash版本4.0以上,理解起来也稍复杂,如果你只需要基础功能,前面的临时文件方案足够稳定好用。
内容的提问来源于stack exchange,提问作者doko
相关产品推荐
相关产品推荐

