Bash脚本重定向标准输出时卡住问题咨询
解决Bash脚本重定向输出卡住的问题
我来帮你搞定这个问题!你的脚本在终端运行正常但重定向输出卡住,核心原因是管道里的head提前关闭输出流,导致sed收到SIGPIPE信号,再加上多次调用外部命令带来的缓冲问题。另外还有几个小细节也影响了脚本的可靠性,比如echo $line没加引号会丢失空格,wc -m会把换行符算进T的计数里。
修复后的脚本
#!/bin/bash # 检查输入文件是否存在 if [ ! -f "$1" ]; then echo "Error: File $1 does not exist!" >&2 exit 1 fi while IFS= read -r line; do # 纯Bash统计行中T的数量,避免调用外部命令 t_chars=${line//[^T]/} t_count=${#t_chars} current_pattern="[GAC]*T" for ((i=0; i<t_count; i++)); do # 用sed的-n选项只输出匹配的前缀,无需head截断 sed -n "s/^\($current_pattern\).*/\1/p" <<< "$line" current_pattern+="[GAC]*T" done done < "$1"
关键优化点
- 正确读取整行:用
IFS= read -r line代替普通的read line,确保读取行内的空格、开头空格和反斜杠时不会被修改或丢失。 - 高效统计T的数量:用Bash内置的字符串替换
${line//[^T]/}删掉所有非T的字符,再取长度${#t_chars},比调用tr和wc更高效,还避免了换行符被误统计的问题。 - 避免管道阻塞:把原来的
echo $line | sed ... | head -n1改成sed -n "s/^\($current_pattern\).*/\1/p" <<< "$line",用sed的-n选项只输出匹配到的前缀,彻底去掉了head——这是导致重定向卡住的核心原因:head拿到第一行就关闭管道,sed未完成输出就被终止,多次循环后引发缓冲阻塞。 - 保留行内空格:用
<<< "$line"(Here字符串)传递行内容给sed,代替echo $line,避免了echo拆分空格的问题,确保处理带空格的行时结果正确。
测试验证
输入行GATTT ATCGT的输出结果和你预期一致:
GAT GATT GATTT AT ATCGT
现在不管是直接在终端运行,还是重定向到文件(比如./script.sh input.txt > output.txt)都能正常工作,不会再卡住啦。
内容的提问来源于stack exchange,提问作者Abir Shaked
相关产品推荐
相关产品推荐

