【问题标题】:How to pipe stderr while leaving stdout alone in ksh?如何在 ksh 中单独留下 stdout 的同时管道 stderr?
【发布时间】:2022-11-20 00:57:05
【问题描述】:

我正在使用 pax 通过 ssh 链接备份目录。如果想要一份进度报告,说明发生了多少转移。使用 -v 选项,它会将它完成的文件名输出到 stderr,所以我想我可以计算目录中有多少文件,并以某种方式将 stderr 输送到我的 shell 脚本中并报告如何到此为止了。

事情是我不确定如何在不中断 stdout 的情况下通过管道传输 stderr。它在远程机器上运行ksh

所以这就是我到目前为止将在远程机器上运行的内容:

file_count=$(find $target -type f | wc -l)
count=0
progress() {
  while [ $((++count)) -lt $file_count ]; do
    echo -n "$((count * 100 / file_count))%\r" 1>&2
    read
  done
  echo 100% 1>&2
}

# This line needs to be modified somehow so that
# stderr goes to progress while leaving stdout
# alone.
echo $target | pax -r -v | progress 

似乎即使 read 说它支持 -n,但它不支持,所以我无法从特定句柄读取。

【问题讨论】:

    标签: pipe ksh stderr


    【解决方案1】:

    在 Bourne shell 中执行此类操作的一般方法是暂时将 stdout 重定向到辅助文件描述符。就像是:

    { cmd 2>&1 1>&3 | progress; } 3>&1
    

    在这里,cmd 的标准输出转到原始标准输出,而cmd 的标准错误转到progress。在你的情况下,你应该写:

    { echo "$target" | pax -r -v 2>&1 1>&3 | progress; } 3>&1 
    

    请注意,来自echo 的任何错误都不会进入到progress 的管道(这可能没问题,并且可能是您想要的),并且您可能需要关注缓冲问题。还要注意 $target 上的双引号。为了健壮性,您应该使用printf '%s ' "$target" 而不是echo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      • 2019-10-26
      • 1970-01-01
      • 1970-01-01
      • 2014-08-28
      • 2023-04-05
      • 2020-09-26
      相关资源
      最近更新 更多