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

子shell脚本运行scp不显示传输文件列表的原因及规避方案

问题原因

scp的默认输出逻辑会检测自身标准输出(stdout)是否绑定到交互式终端(TTY):

  • 直接在交互式shell运行脚本时,scp的stdout指向终端,会正常输出每个传输的文件列表
  • 当你通过$()命令替换、管道将my_script的stdout接入tee时,scp的stdout直接连接的是管道而非终端,scp检测到非交互输出环境后,会默认关闭传输文件列表的输出,避免管道处理场景下的日志干扰。

注意:即使你通过tee将输出重定向到绑定终端的/dev/fd/5,scp只会检测自身第一层stdout的连接对象,不会识别最终输出终点,因此仍然不会输出列表

规避方案(无需使用scp -v)
  • 方案1:使用unbuffer工具(属于expect软件包)为scp分配伪终端,模拟交互环境,修改my_script中的scp命令为:
unbuffer scp -- 'somehost:*.txt' dest_dir

该方案会欺骗scp判定自身运行在交互终端下,正常输出传输文件列表。

  • 方案2:使用script命令模拟终端环境运行my_script,无需修改原my_script的内容,将第二个脚本的捕获逻辑修改为:
exec 5>&1
foo=$(script -q -c my_script /dev/null | tee /dev/fd/5) || exit -1

script命令默认会为执行的命令创建伪终端,同样可以触发scp的交互模式输出。

  • 方案3:如果你不需要将scp的传输列表存入变量foo,仅需要打印到终端,可以将scp的输出重定向到标准错误(stderr),修改my_script的scp命令为:
scp -- 'somehost:*.txt' dest_dir >&2

命令替换$()默认仅捕获标准输出,scp输出到stderr后会直接打印到终端,不会被管道捕获。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:27:03