0

我有这个功能:

psyu() {
    sudo pacman -Syu --noconfirm | grep -q 'non ci sono aggiornamenti'
    [ $? != 0 ] &&
        notify-send -i /usr/share/icons/arch.png "Packages upgraded" ||
        notify-send -i /usr/share/icons/arch.png "Nothing to upgrade or there was an error"
}

(我是意大利人,所以我检查了“没有更新”的意大利语翻译。我不知道该怎么做,因为 pacman 没有针对不同情况的不同退出代码。)

我希望终端中的命令输出正常(可视化所有 pacman 标准输出),但我也想使用 grep 使该功能正常工作。

让我知道是否有更好的方法来做到这一点。

4

3 回答 3

3

使用临时文件描述符将输出转发到标准输出。不需要使用$?,只需将管道放入if.

{
if 
    sudo pacman -Syu --noconfirm |
    tee >(cat >&3) |
    grep -q 'non ci sono aggiornamenti'
then 
    notify-send -i /usr/share/icons/arch.png "Packages upgraded"
else
    notify-send -i /usr/share/icons/arch.png "Nothing ..."
fi
} 3>&1

或者更清洁:

if {
       sudo pacman -Syu --noconfirm |
       tee >(cat >&3) |
       grep -q 'non ci sono aggiornamenti'
   } 3>&1
then 
    notify-send -i /usr/share/icons/arch.png "Packages upgraded"
else
    notify-send -i /usr/share/icons/arch.png "Nothing ..."
fi
于 2020-04-28T21:46:04.487 回答
1

您可以使用teeto 复制pacman的标准输出并将其中一个副本重定向到当前进程的控制 tty;在 Linux 上,它可以作为/dev/tty

sudo pacman -Syu --noconfirm |
  tee /dev/tty |
  if grep -q 'non ci sono aggiornamenti'; then
    notify-send -i /usr/share/icons/arch.png "Nothing ..."
  else
    notify-send -i /usr/share/icons/arch.png "Packages upgraded"
  fi

或者,您可以使用checkupdatesfrom pacman-contrib。它的退出状态是2没有可用更新时:

checkupdates 1>/dev/null
if test "$?" -eq 2; then
  message="Nothing to upgrade or there was an error"
else
  sudo pacman -Syu --noconfirm
  message="Packages upgraded"
fi
notify-send -i /usr/share/icons/arch.png -- "$message"

请注意,在您的函数和我的第一个代码片段中,始终if执行一个分支(或 AND/OR 列表中的一个命令) ,当以错误终止时会给您一个误导性通知。 还要考虑到这一点,您需要将' 输出的副本发送到临时文件,因为您无法捕获' 的退出状态在同一管道中使用 ( ) 其输出:pacman
pacmanpacmangrep

psyu () (
  set -o pipefail
  trap 'rm -rf -- "$tmpdir"' EXIT
  tmpdir=$(mktemp -d)
  tmpfile="$tmpdir/pacman.out"
  if ! sudo pacman -Syu --noconfirm |
    tee -- "$tmpfile"
  then
    message="pacman: Some error occurred"
  elif grep -q -- 'non ci sono aggiornamenti' "$tmpfile"; then
    message="Nothing to upgrade"
  else
    message="Packages upgraded"
  fi
  notify-send -i /usr/share/icons/arch.png -- "$message"
)

pipefail需要 shell 选项以允许测试也捕获管道第一阶段中发生的if错误(否则它的退出状态将是最后一个命令的退出状态)。
最后,请注意函数定义在括号()中,以避免在调用 shell 中设置陷阱和选项。

于 2020-04-28T21:28:19.763 回答
0

我相信你可以在这里使用 awk:

sudo pacman -Syu --noconfirm|
  awk '1;/non ci sono aggiornamenti/{r=7};END{exit(r)}'
[ $? != 7 ] && notify-send -i /usr/share/icons/arch.png "Packages upgraded" ||
  notify-send -i /usr/share/icons/arch.png "Nothing to upgrade or there was an error"

awk 的意思是:打印来自 pacman 的所有行(这是唯一的做法1)。如果输出中存在“non ci sono aggiornamenti”,则设置r=7。最后,终止并返回退出代码(如果找到匹配则返回 7,否则返回 0)。

我在那里使用了 7,因为该错误不太可能用于指示另一个常见错误,但原则上它可以是任何非零值。

于 2020-04-28T21:36:32.570 回答