【问题标题】:How to capture output of several commands?如何捕获多个命令的输出?
【发布时间】:2013-12-01 19:30:06
【问题描述】:

我有命令产生属于不同命令的输出。

s=$(time dd if=<source> of=/dev/null bs=<number> count=<number> 2>&1)

$s 将仅包含来自 dd 命令的输出。我怎样才能拥有另一个包含来自time 的输出的变量?

【问题讨论】:

标签: linux bash shell time


【解决方案1】:

尝试以下方法:

s=$({ time dd ... > /dev/null;} 2>&1)

Chepners 的回答给了我灵感,可以说是更好的:

s=$(exec 2>&1; time dd ... > /dev/null)

$() 已经是一个子shell,所以不需要创建额外的子shell。将exec 2&gt;&amp;1; 放在命令之前会重定向整个子shell 的标准输出,将其放在命令之后会使它成为time 的命令的一部分,因此仅适用于传递给time 的命令。省略exec 和分号将尝试执行系统time 二进制intead,如果不存在则出错。仅省略 exec 但保留分号将不起作用,因为这将导致仅重定向新分叉的进程,并且内置的 time 将不是新进程。

哦,顺便说一句,&gt; /dev/null 不会将time 本身的输出转储到 /dev/null,因为它也是time 执行的命令的一部分,并且不会应用于时间本身。

【讨论】:

  • @JonathanLeffler,s=$( exec 2&gt;&amp;1; time dd if=something of=/dev/null ) 确实是一种更可预测的行为;-)
  • 安静地忽略我...我打错了你指定的内容。
  • @which,我已经尝试过你的命令,'s=$(2>&1 time > /dev/null) 它返回,-sh: time: command not found。我有 GNU bash,版本 4.1.5。
  • @wich,没有exec,它在我的 bash shell 中不起作用。我似乎记得一个单独的2&gt;&amp;1 重定向了前一个命令的输出,当新的shell 启动时该命令不存在。所以将会发生的事情有点不可预测,并且在 shell 版本之间似乎有所不同。但是,shell 开头的exec 2&gt;&amp;1 被很好地记录为“全局”重定向,因此我发表了评论。 :-)
  • @yart 确实,似乎这种语法在 Bash 4 上不再适用。或者实际上可能是没有分号 bash 试图调用系统二进制文件而不是内置文件,我不是100 确定。无论如何,在重定向和时间之间添加一个分号可以解决它。我更新了答案。
【解决方案2】:

你好,我刚刚找到答案。

来自 Vlad 在 cmets 中的链接给了我方向。

我可以使用子shell。

可以指定我的命令

s=$((time dd if=<source> of=/dev/null bs=<number> count=<number> 2>&1 | tail -n1) 2>&1)

然后我可以拥有包含所有数据的 $s 变量,我可以拥有数组并获取值。

【讨论】:

    【解决方案3】:

    bash 内置 time 是一个特殊的内置,它写入当前 shell 的标准错误,所以你不能简单地重定向它的输出。相反,您需要在其标准错误已被重定向的子 shell 中运行它。这会导致“真实”命令在子shell 中运行,因此您不能简单地将其输出分配给变量,因为该变量将随子shell 消失。试试这个:

    s=$( exec 2>time.txt; time echo foo )
    t=$(< time.txt)
    

    【讨论】:

      猜你喜欢
      • 2010-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 2013-01-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多