Shell-Script

基於返回值而不是退出程式碼建構管道的優雅方式?

  • January 5, 2018

當狀態碼沒用的時候,有沒有辦法根據stdout的輸出來建構管道呢?

我希望答案不是針對案例,而是針對 shell 腳本範圍內的問題。我要做的是通過根據國家和語言程式碼猜測名稱來找到儲存庫中可用的最具體的包。

以這個為例,

  • $PACKAGE1=hunspell-en-zz
  • $PACKAGE2=hunspell-en

第一個猜測更合適,但可能不存在。在這種情況下,我想返回hunspell-en( $PACKAGE2),因為第一個選項hunspell-en-zz( $PACKAGE1) 不存在

apt-cache 的管道

只要命令能夠執行(來自 的文件),該命令apt-cache就會返回成功(由 shell 定義為退出程式碼零apt-cache

apt-cache 在正常操作時返回零,在錯誤時返回十進制 100。

這使得在管道中使用該命令更加困難。通常,我希望 404 的包搜尋等效項會導致錯誤(就像 or 會發生的那樣curlwget。我想搜尋一個包是否存在,如果不存在則回退到另一個包

||這不返回任何內容,因為第一個命令返回成功(因此永遠不會執行的 rhs )

apt-cache search hunspell-en-zz || apt-cache search hunspell-en

apt-cache search有兩個論據

這不會返回任何內容,因為apt-cache它的參數是 AND,

apt-cache search hunspell-en-zz hunspell-en

從文件apt-cache

可以使用單獨的參數來指定多個搜尋模式,這些搜尋模式一起使用。

因此,由於其中一個論點顯然不存在,因此不會返回任何內容。

問題

apt-cache處理返回程式碼對任務無用的約定之類的約定的 shell 習慣用法是什麼?成功僅取決於 STDOUT 上是否存在輸出?

如同

他們都源於同一個問題。那裡選擇的答案提到find -z了哪些在這裡不適用的解決方案並且是特定於案例的。沒有提到不使用空終止的成語或建構管道(不是 on 的選項apt-cache

創建一個接受命令並返回 true 的函式,前提是它有一些輸出。

r() { local x=$("$@"); [ -n "$x" ] && echo "$x"; }

( ( r echo -n ) || echo 'nada' ) | cat      # Prints 'nada'
( ( r echo -n foo ) || echo 'nada' ) | cat  # Prints 'foo'

所以對於這個案例,它會像這樣工作,

r apt-cache search hunspell-en-zz || r apt-cache search hunspell-en

據我所知,沒有標準的方法來處理命令的成功取決於輸出的存在的情況。不過,您可以編寫解決方法。

例如,您可以將命令的輸出保存在變數中,然後檢查該變數是否為空:

output="$(command)"

if [[ -n "${output}" ]]; then
 # Code to execute if command succeded
else
 # Code to execute if command failed
fi

我認為這以一般方式回答了這個問題,但是如果我們談論apt-cache search一些解決方案,我會想到一些解決方案。

我有一個腳本,它使包管理更容易。它的一些功能是:

search() {
 local 'package' 'packages'
 packages="$( apt-cache search '.*' | cut -d ' ' -f '1' | sort )"
 for package; do
   grep -F -i -e "${package}" <<< "${packages}"
 done
}


search_all() {
 local 'package'
 for package; do
   apt-cache search "${package}" | sort
 done
}


search_description() {
 local 'package' 'packages'
 packages="$( apt-cache search '.*' | sort )"
 for package; do
   grep -F -i -e "${package}" <<< "${packages}"
 done
}


search_names_only() {
 local 'package'
 for package; do
   apt-cache search --names-only "${package}" | sort
 done
}

這些使您可以在單個命令中進行多次搜尋。例如:

$ search hunspell-en-zz hunspell-en
hunspell-en-au
hunspell-en-ca
hunspell-en-gb
hunspell-en-med
hunspell-en-us
hunspell-en-za

每個函式都以不同的方式搜尋數據庫,因此結果可能會因您使用的函式而異:

$ search gnome | wc -l
538
$ search_all gnome | wc -l
1322
$ search_description gnome | wc -l
822
$ search_names_only gnome | wc -l
550

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