Как получить код завершения grep, не влияя на стандартный вывод команды piped - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть эта функция:

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 для функция для работы.

Дайте мне знать, если есть лучший способ сделать это.

Ответы [ 3 ]

3 голосов
/ 29 апреля 2020

Пересылать вывод на стандартный вывод с временным дескриптором файла. Использование $? не нужно, просто поместите конвейер в 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
1 голос
/ 29 апреля 2020

Вы можете использовать tee, чтобы продублировать стандартный вывод 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

В качестве альтернативы, вы можете использовать checkupdates из 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 (или одна из команд в Ваш И / ИЛИ список) всегда выполняется, давая вам вводящее в заблуждение уведомление, когда pacman завершается с ошибкой.
Для того, чтобы учесть это, вам необходимо отправить копию pacman вывод во временный файл, потому что вы не можете перехватить pacman состояние выхода и использовать (grep) свой вывод в том же конвейере:

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"
)

* 1027 Опция * shell необходима, чтобы позволить тесту if также отлавливать ошибки, возникающие на первом этапе конвейера (в противном случае его состояние выхода будет равно состоянию последней команды).
Наконец, обратите внимание, что определение функции находится в Скобки () во избежание установки ловушек и параметров в вызывающей оболочке.

0 голосов
/ 29 апреля 2020

Я полагаю, вы можете использовать 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 (это то, что делает lone 1). Если в выходных данных есть «non ci sono aggiornamenti», установите r=7. В конце завершите работу и верните код выхода (7, если совпадение найдено, иначе 0).

Я использовал 7 там, потому что весьма маловероятно, что эта ошибка будет использоваться для сигнализации о другой распространенной ошибке, но в принципе это может быть любое ненулевое значение.

...