簡體   English   中英

Bash-如果第一個使用者失敗,則在管道中重用輸出

[英]Bash - reuse the output in pipes if the first consumer fails

我的操作費用很高( curl調用)。 這可能會或可能不會產生JSON。 如果是這樣,我想使用json_pp漂亮地打印它。 但是,如果失敗,我想按原樣打印。

這就是我現在所擁有的:

filter "$ENVI" "$2" running | dns_ \
   | xargs  -L1 --max-args=1 -I{} $DEBUG_XARGS --no-run-if-empty \
   sh -c "echo 'Versions at {}': ; curl --fail http://... | json_pp"

相關部分是

curl --fail http://... | json_pp

當輸出為JSON時,就可以了。 但是當不是的時候,我得到:

格式錯誤的JSON字符串,數組,對象,數字,字符串或原子都不是,位於/ usr / bin / json_pp第45行的字符偏移量0(“ Version:18.4.0,bui ...”之前)。

我想以某種方式對json_pp的錯誤代碼做出反應,以便如果它不為0 ,則輸出將在管道中進一步傳遞( cat將接收它的位置),但是如果它返回0 (接受JSON),則管道不會繼續(或繼續json_pp的輸出)。

換句話說,我想跳過失敗的管道中的步驟。
我該如何實現? 尋找類似的東西

curl --fail http://... | ifTheFollowingFailsThenPassAsIsOtherwiseUseOutputOf json_pp | cat

因為這一切都發生在xargs ,所以我正在尋找一個簡短的解決方案,例如tee 它也可能是Bash函數。

tryOrCat() {
  local input output
  input=$(cat) || return
  if output=$("$@" <<<"$input"); then
    printf '%s\n' "$output"
  else
    printf '%s\n' "$input"
  fi
}

...此后:

whatever | tryOrCat json_pp

這是我發布后一段時間想出來的:

bbTmp=$(mktemp "${TMPDIR:-/tmp}/bbPp.XXXXXX")
export bbTmp # to be available to sh -c

filter "$ENVI" "$2" running | dns_ | xargs  -L1 --max-args=1 -I{} --no-run-if-empty \
  sh -c 'curl --fail http://{}/... | tee "$bbTmp" | json_pp 2>/dev/null || cat "$bbTmp"'

就像我需要的那樣。 感謝其他提示,對於更通用的解決方案將很有用。

管道中的輸出只能處理一次。 您需要復制它或保存它。 后者很容易:

json=$(curl --fail http://...)
json_pp <<< "$json" || printf '%s\n' "$json"

這將使json_pp的錯誤消息可見。 如果要隱藏它,可以重定向stderr:

json_pp <<< "$json" 2>/dev/null || printf '%s\n' "$json"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM