如何重定向scp命令匹配指定模式的输出到文件
问题原因
之前的grep写法不生效,核心原因是scp产生的Permission Denied类错误信息默认输出到标准错误流(stderr,文件描述符2),shell管道|默认仅转发*标准输出流(stdout,文件描述符1)*的内容,错误信息会直接打印到终端,不会进入grep匹配流程,因此无法写入目标文件。
注意重定向顺序直接影响结果:全量写日志的命令source my_scp_script.sh > output.log 2>&1是正确的全量重定向写法,但过滤场景需要调整流指向,避免正常传输的成功日志进入grep。
可用方案
方案1:标准流重定向+grep过滤(兼容所有POSIX shell)
执行以下命令即可仅将权限拒绝的错误行写入output.log,正常传输的成功输出会直接丢弃:
source my_scp_script.sh 2>&1 >/dev/null | grep ': Permission denied' > output.log
写法说明:
- 重定向顺序
2>&1 >/dev/null不可调换:先将stderr绑定到管道输入侧(后续传给grep处理),再将原本走stdout的正常传输信息重定向到/dev/null直接丢弃 - grep匹配规则写为
: Permission denied是为了精准匹配scp固定报错格式scp: <文件路径>: Permission denied,避免把scp输出到stderr的进度条信息误匹配
如果需要在终端实时查看正常传输进度,仅把权限错误单独存入日志,可以调整为:
source my_scp_script.sh 2>&1 | tee /dev/tty | grep ': Permission denied' > output.log
方案2:进程替换写法(支持Bash/Zsh等现代shell,逻辑更直观)
如果不需要兼容POSIX标准sh,可以用进程替换直接单独处理stderr流,无需记忆重定向顺序:
source my_scp_script.sh >/dev/null 2> >(grep ': Permission denied' > output.log)
该写法直接丢弃stdout内容,仅把stderr内容送入grep过滤后写入日志,效果和方案1完全一致,更不容易因为重定向顺序写错导致结果异常。
内容的提问来源于stack exchange,提问作者milkyway
相关产品推荐
相关产品推荐

