You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSH调用破坏Bash脚本I/O重定向,求无临时文件解决办法

问题说明

先看原始脚本save_stdin.sh:

$ cat save_stdin.sh 
#!/bin/bash

# 保存标准输入
exec 3<&0

echo " intermediate output independing from stdin:"
echo "This is a test " | grep "test" | tr '[:lower:]' '[:upper:]'

# 重置标准输入
exec 0<&3

echo -e "\n work with original stdin:"
ssh localhost grep "piped" | tr '[:lower:]' '[:upper:]'

# 关闭已保存的标准输入
exec 3<&-

执行命令echo "this is piped" | ./save_stdin.sh,能得到预期输出:

$ echo "this is piped" | ./save_stdin.sh 
 intermediate output independing from stdin:
THIS IS A TEST 

 work with original stdin:
THIS IS PIPED

但如果在重置标准输入前插入ssh localhost ps | wc -l命令,修改后的脚本如下:

#!/bin/bash

# 保存标准输入
exec 3<&0

echo " intermediate output independing from stdin:"
echo "This is a test " | grep "test" | tr '[:lower:]' '[:upper:]'

##
ssh localhost ps | wc -l
##

# 重置标准输入
exec 0<&3

echo -e "\n work with original stdin:"
ssh localhost grep "piped" | tr '[:lower:]' '[:upper:]'

# 关闭已保存的标准输入
exec 3<&-

此时执行同样的命令,输出异常:

$ echo "this is piped" | ./save_stdin.sh 
 intermediate output independing from stdin:
THIS IS A TEST 
86

 work with original stdin:

可见原本保存的标准输入被破坏,需要在不创建临时文件的前提下解决这个问题。

原因分析

问题根源在ssh命令上:当ssh未指定标准输入来源时,会默认继承当前进程的stdin。插入的ssh localhost ps | wc -l中,ssh会读取管道传入的"this is piped"内容并将其耗尽,导致后续恢复stdin后,已经没有内容可读取了。

解决方法

给中间执行的ssh命令显式指定不读取原stdin,有两种简单方式:

方式1:重定向ssh的标准输入到/dev/null

把插入的ssh命令修改为:

ssh localhost ps < /dev/null | wc -l

方式2:使用ssh的-n参数

ssh的-n参数会阻止它读取标准输入,效果等同于重定向到/dev/null,命令修改为:

ssh -n localhost ps | wc -l
修复后的完整脚本
#!/bin/bash

# 保存标准输入
exec 3<&0

echo " intermediate output independing from stdin:"
echo "This is a test " | grep "test" | tr '[:lower:]' '[:upper:]'

## 二选一即可
ssh -n localhost ps | wc -l
# 或者 ssh localhost ps < /dev/null | wc -l

# 重置标准输入
exec 0<&3

echo -e "\n work with original stdin:"
ssh localhost grep "piped" | tr '[:lower:]' '[:upper:]'

# 关闭已保存的标准输入
exec 3<&-
验证结果

执行echo "this is piped" | ./save_stdin.sh,输出恢复正常:

$ echo "this is piped" | ./save_stdin.sh 
 intermediate output independing from stdin:
THIS IS A TEST 
86

 work with original stdin:
THIS IS PIPED

内容的提问来源于stack exchange,提问作者nefuson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:05:01