【问题标题】:STDOUT of nested commands in BashBash 中嵌套命令的 STDOUT
【发布时间】:2017-10-14 15:06:51
【问题描述】:

对 bash 很陌生 - 我正在尝试将 /usr/bin/time 命令的输出存储到 TIME_INFO 变量中,该变量适用于以下设置...但是我也希望能够存储其他一些嵌套命令(例如 /usr/local/bin/firejail 或 ./program)的输出到其他变量。目前,如果 ./program 中存在运行时异常,它也会转到 TIME_INFO 变量。

TIME_INFO=$( /usr/bin/time --quiet -f "%e-%U-%S-%M-%x" 2>&1 \
timeout 5s \
/usr/local/bin/firejail --quiet --cgroup=/sys/fs/cgroup/memory/group1/tasks --profile=java.profile \
./program < test.in > test.out )

有没有办法实现多个嵌套命令的输出分离?

提前致谢!

【问题讨论】:

  • 这对于临时文件来说无疑是最简单的。你对它们的使用还满意吗?
  • 是的,我只是使用数据来汇总脚本运行的每个进程的信息,这样就可以了。
  • 请参阅capture stdout and stderr in different variables,了解密切相关的操作是什么样子没有使用临时文件。
  • 如果您不是在寻找错误,在$(...) 中执行2&gt;&amp;1 可能不是一个好主意。
  • @MadPhysicist 抱歉,我有点不清楚 - 根据手册页,时间命令默认输出到 stderr。

标签: linux bash


【解决方案1】:

一种方法是在调用链中注入一个 shell 并让它负责修改其子进程的 stderr:

time_info=$( /usr/bin/time --quiet -f "%e-%U-%S-%M-%x" 2>&1 \
  sh -c '"$@" 2>"$0"' test.err \
    timeout 5s \
      /usr/local/bin/firejail \
          --quiet --cgroup=/sys/fs/cgroup/memory/group1/tasks --profile=java.profile \
        ./program < test.in > test.out )

# read your content back into a shell variable
error_text=$(<test.err)

这里的相关更改是sh -c '"$@" 2&gt;"$0",它将其参数作为命令运行,stderr 重定向到$0 中传递的文件名——它由紧跟在sh -c 传递的代码后面的字符串填充。

请注意,我修改了 TIME_INFO 变量 per POSIX guidance 的大小写,为对 shell 或 OS 有意义的变量指定全大写名称,并为其他目的保留至少一个小写字符的名称.

【讨论】:

  • 你能完全忽略 stderr 吗?
  • @MadPhysicist,当然——如果你用/dev/null 代替test.err,就会产生这种效果。不过,我不确定这是 OP 的意图。 (不能为 entire 命令丢弃 stderr,因为它是存储 time 输出的位置。
  • @MadPhysicist,...也就是说,您指出,既然我们想要保留来自 time 的 stderr,我真的应该将 shim 更早地放在调用树中。跨度>
  • @CharlesDuffy 这很完美,谢谢!但是,如果您想获得每个子命令的输出,可能会有些混乱。也为 posix 语法上的一点点欢呼。
猜你喜欢
  • 2014-04-05
  • 2017-02-02
  • 2015-01-16
  • 1970-01-01
  • 2017-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-01
相关资源
最近更新 更多