如何在不使用 stdio 和 stderr 的情况下获取命令替换的结果?

如何在不使用 stdio 和 stderr 的情况下获取命令替换的结果?

我有一个用户提供的 bash 脚本,它以某种方式创建目录并输出其路径。它可以以多种方式工作,例如,它可以克隆 git 存储库,进行一些设置,然后输出路径。如下所示:

git clone ...repo --quiet && echo "...path"

我使用命令替换来运行它,使用换行符$(...)并使用结果路径。如下所示:

path=$(...)

命令本身是用户提供的,所以它可以是任何东西,我不能预料它总是 git clone。

它运行良好,但如果最终命令之前的命令echo输出任何内容,它就会弄乱结果。我可以将所有前面的命令的 stdout 重定向到 stderr,并且只在最后一步使用 stdout,但我觉得这是一种 hack。

有没有办法将 stdout 和 stderr 留给调用者的 stdout 和 stderr,但为结果设置单独的流?

答案1

这将保存最后一行输出:

path=$(whatever | tail -n 1)

如果您需要以某种方式利用所有输出:

  • 用于tee将输出打印到 tty

    path=$(whatever | tee /dev/tty | tail -n 1)
    
  • 或者保存它

    path=$(whatever | tee ./file | tail -n 1)
    
  • 或者处理它(并打印到 tty 或文件,不是到标准输出来提供变量)

    path=$(whatever | tee >(grep foo | wc -c >/dev/tty) | tail -n 1)
    
  • 您甚至可以将输出发送(分叉)到许多目的地:

    path=$(whatever | tee /dev/tty ./file /some/named/fifo >(tool1) | tail -n 1)
    

显然,回显路径内的换行符会破坏解决方案。


echo如果您可以修改用户提供的脚本中的最终命令,请参阅我的这个答案寻找使用临时文件的方法。

相关内容