1

我正在尝试设置一小段代码,以便如果其中任何一段失败,它将触发另一行代码运行。就像:

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”语句(如果你想这样称呼它)甚至不存在。此外,它的第一部分,特别是在管道之前,是如果它失败它不会抛出错误的部分。我对管道的第二部分没有任何问题,所以我不确定它是否会表现出相同的行为。

提前致谢!

4

3 回答 3

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

如果您在子shell ie 中运行这些命令没有问题,这应该对您有用()

于 2019-08-08T01:23:05.557 回答
1

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

$ cat a.sh
#!/bin/bash

false | true || echo executed 1
set -o pipefail
false | true || echo executed 2
$ ./a.sh
executed 2
于 2019-08-08T03:29:38.890 回答
0

您可以使用进程替换来使退出状态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
于 2019-08-08T01:45:42.867 回答