簡體   English   中英

管道中失敗的命令未觸發“捕獲”命令

[英]failed command in pipeline not triggering “catch” command

我正在嘗試設置一小段代碼,以便如果其中任何一段失敗,它將觸發另一行代碼運行。 像這樣:

cmd1 || cmd2

但是,第一段中有一個管道,因此:

cmd1 | cmd2 || cmd3

但是,如果cmd1失敗,則cmd3不會運行。

如果嘗試了以下操作,則每次結果相同:

( cmd1 | cmd2 ) || cmd3
{ cmd1 | cmd2 } || { cmd3 }

為了完整起見,這是我正在使用的特定代碼塊:

{
        {
            pkexec apt -y install (package-file-name) | zenity --progress --pulsate --auto-close --no-cancel --text="installing (package-name) . . ." 

        } && {
            notify-send "(package-name) has been installed"
        }
} || {
        zenity --error --text="Error code: $?"
}

到目前為止,它的運行就好像“ catch”語句(如果要調用它)甚至不存在一樣。 另外,它的第一部分,特別是在管道之前的部分是,如果失敗,則不會引發錯誤。 我在管道的第二部分上沒有任何問題,所以我不確定它是否會表現出相同的行為。

提前致謝!

( cmd1 | cmd2 ; exit ${PIPESTATUS[0]}) || cmd3

如果您在子外殼程序()運行這些命令沒有問題,這應該對您有用。

在bash中,您可以設置pipefail 例如:

$ cat a.sh
#!/bin/bash

false | true || echo executed 1
set -o pipefail
false | true || echo executed 2
$ ./a.sh
executed 2

您可以使用進程替換使zenity的退出狀態無關緊要。

if pkexec apt -y install (package-file-name) > >(
     zenity --progress --pulsate --auto-close --no-cancel --text="installing (package-name) . . ."
   ); then 
    notify-send "(package-name) has been installed"
else
    zenity --error --text="Error code: $?"
fi

另外,您可以使用顯式命名管道來避免需要任何非標准的shell擴展。

mkfifo p
zenity --progress --pulsate --auto-close --no-cancel --text="installing (package-name) . . ." < p &

if pkexec apt -y install package-file-name > p; then
    notify-send "(package-name) has been installed"
else
    zenity --error --text="Error code: $?"
fi

暫無
暫無

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

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