Pipe

如何防止 curl 輸出列印前一個管道的輸出?

  • March 28, 2021

我有一個命令將加密的 gpg 流通過管道傳輸到 curl 中:

echo "Some Text" | gpg -o - | curl --silent -T - \
-X PUT \
--output /dev/null \
${myurl} \

執行時,我看到類似

% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
 0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Enter passphrase

Passphrase:

"Enter passphrase"部分附加到 curl 輸出的發送。由於事物的管道性質,我無法換行。有沒有辦法讓 curl 輸出稍後執行?

如何防止 curl 輸出列印前一個管道的輸出?

curl不列印“前一個管道的輸出”。curl發生的事情是將gpg一些消息列印到您的終端。消息相互干擾。

請記住,管道命令同時執行


如果您希望成功的輸出gpg永遠不會為空,請使用ifne

… | gpg … | ifne curl …

(在 Debianifne中是在moreutils包中。)

的主要目的ifne是防止curl在標準輸入為空時執行命令(此處為:)。要知道標準輸入是否真的為空,該工具需要等待任何數據或 EOF。這會延遲實際命令。你需要的是延遲。

我希望gpg只有在獲得正確的密碼後才能開始列印。我沒有ifne在之前gpg詢問密碼時進行徹底測試,但我確實通過sudo …詢問密碼進行了測試。如果gpg按我的預期工作,那麼ifne可以幫助你。它會curl在您提供密碼後執行。

如果不向其標準輸出列印任何內容(例如,因為密碼錯誤),Noteifne將阻止curl執行。gpg這種行為通常是需要的。但是,如果成功的輸出gpg可以是空的並且仍然應該通過管道傳送到curl,那麼ifne單獨是不正確的。

如果您想執行curl而不管是否gpg列印任何內容,請繼續閱讀。


下面的程式碼是這個答案report中我的腳本的簡化版本。將其另存為.delay

ifne以更複雜的方式使用。程式碼必須是可執行腳本(我的意思是不要嘗試將其設為 shell 函式),因為它通過呼叫自身ifne "$0"(並且ifne無法執行函式)。

#!/bin/bash

if [ "$1" = "-X" ]; then
  marker=1
  fd="$2"
  shift 2
else
  unset marker
  exec {fd}>&1
fi

if [ "$marker" ]; then
  ( >&"$fd" "$@" )
else
  ifne -n "$0" -X "$fd" "$@" | ifne "$0" -X "$fd" "$@"
fi

的目的delay是延遲命令的執行,直到標準輸入中有數據或 EOF。它被設計為在|.

你應該像這樣使用它:

… | gpg … | delay curl …

curl只有在gpg開始列印到其標準輸出或出於任何原因關閉後才會執行。

已經連結的答案中解釋了一些技術細節。


和之間ifne foo的區別:ifne -n foo``delay foo

  • ifne foo等待數據或 EOF,然後在foo有數據時執行,
  • ifne -n foo等待數據或 EOF,然後在foo沒有數據時執行,
  • delay foo等待數據或 EOF,然後foo無條件執行。

引用自:https://unix.stackexchange.com/questions/642443