【问题标题】:Bash: log a message between execution of two commands in a pipelineBash:在管道中执行两个命令之间记录一条消息
【发布时间】:2021-06-29 15:49:30
【问题描述】:

编辑:感谢所有答案。我现在明白我要的是废话。

我有以下命令可以下载和解压缩档案:

curl -fSL "$uri" | tar -xz

我想要的是在下载后显示一条消息,然后用 tar 解压下载的存档。

我知道可以将下载的存档保存到文件中,然后执行其他任何操作然后解压缩。但是是否可以在不保存到文件的情况下做到这一点?使用标准输入和标准输出?

【问题讨论】:

  • 对信息性消息使用标准错误,而不是标准输出。
  • 你要求的东西是不可能的,因为这两个命令之间没有“之间”这样的东西。 curltar 命令同时运行。当curl 将下载的内容块写入其标准输出时,tar 读取该内容并开始解包,而curl 仍在忙于下载更多内容。
  • ...现在,当然可以有一个额外的管道组件负责状态跟踪(与 curl 和 tar 同时运行),这是一项工作,有像 pv 这样的预先存在的工具已经写好了。
  • 管道就是管道。 tar 在第一个字节下载完成后已经开始解包。
  • ...并将其分成两部分,一个接一个地发生,这会比保持原样更慢。 (下载到内存不使用 I/O 带宽,解压也不依赖于网络带宽,所以同时做这两件事比在一台机器上一个接一个地做更有效地利用资源只有一个 CPU 内核;更不用说这意味着您不需要一个地方来存储下载但尚未解压的内容)。

标签: bash curl stdout stdin tar


【解决方案1】:

curl 完成后,您可以使用组 {} 打印一些内容。要在终端中显示消息而不将其传递给tar,我们可以通过任何未使用的文件描述符(此处为3)来路由它。

{ { curl -fSL "$uri"; echo "download complete" >&3; } | tar -xz; } 3>&1

由于curltar 并行运行,后者可能会在打印download complete 的同一瞬间完成。因此,一个简单的curl -fSL "$uri" | tar -xz; echo "Everything done" 可能也一样好。

在你写的问题中......

下载后显示一条消息然后解压下载的存档

如果你真的想暂停tar直到下载完成,那么你可以使用GNU moreutils中的sponge。但是,这样做没有任何好处。

{ { curl -fSL "$uri"; echo "download complete" >&3; } | sponge | tar -xz; } 3>&1

【讨论】:

  • ...虽然如果这是一个大文件(或者真的,任何除了一个彻头彻尾的小文件),tar 将在download complete 时几乎完成打印,因此尚不清楚这样做的实际好处是什么。如果tarcurl 慢得多,管道上的背压将迫使下载速度变慢,因此它们几乎同时完成。
  • (另外,如果这是为了作为信息日志,stdout——虽然是用户要求的——不适合它)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 2017-12-20
相关资源
最近更新 更多