Подтвердить что ты не робот

Как сделать "если не истинное условие"?

Я бы хотел, чтобы команда echo выполнялась, когда cat /etc/passwd | grep "sysa" не соответствует true.

Что я делаю неправильно?

if ! [ $(cat /etc/passwd | grep "sysa") ]; then
        echo "ERROR - The user sysa could not be looked up"
        exit 2
fi
4b9b3361

Ответ 1

попробовать

if ! grep -q sysa /etc/passwd ; then

grep возвращает true, если находит цель поиска, и false, если это не так.

Итак, НЕ false == true.

if оценка в оболочках спроектирована так, чтобы быть очень гибкой и много раз не требует цепей команд (как вы писали).

Кроме того, если посмотреть на ваш код как есть, то вам следует рекомендовать использование формы cmd-замены $( ... ), но подумайте о том, что выходит из процесса. Попробуйте echo $(cat /etc/passwd | grep "sysa"), чтобы понять, что я имею в виду. Вы можете сделать это, используя параметр -c (count) для grep, а затем выполните if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then, который работает, но скорее старая школа.

НО, вы можете использовать новейшие функции оболочки (арифметическая оценка), например

if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`

который также дает вам преимущество использования операторов сравнения на основе c-lang, ==,<,>,>=,<=,% и, возможно, нескольких других.

В этом случае, за комментарий Orwellophile, арифметическая оценка может быть уменьшена еще дальше, например

if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....

ИЛИ

if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....

Наконец, есть награда под названием Useless Use of Cat (UUOC).:-) Некоторые люди будут прыгать вверх и вниз и плакать готкой! Я просто скажу, что grep может взять имя файла в своей cmd-строке, поэтому зачем вызывать дополнительные процессы и конструкции трубопроводов, когда вам это не нужно?;-)

Надеюсь, это поможет.

Ответ 2

Я думаю, что это можно упростить:

grep sysa /etc/passwd || {
    echo "ERROR - The user sysa could not be looked up"
    exit 2
}

или в одной командной строке

$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }

Ответ 3

Что я делаю неправильно?

$(...) содержит значение, а не статус выхода, поэтому этот подход неверен. Однако в этом конкретном случае это действительно работает, потому что sysa будет напечатано, что делает утверждение теста реальным. Однако if ! [ $(true) ]; then echo false; fi всегда печатает false, потому что команда true ничего не записывает в stdout (даже если код выхода равен 0). Вот почему его нужно перефразировать до if ! grep ...; then.

Альтернативой будет cat /etc/passwd | grep "sysa" || echo error. Редактировать, как указал Алекс, здесь бесполезно: grep "sysa" /etc/passwd || echo error.

Нашли другие ответы довольно запутанно, надеюсь, что это поможет кому-то.

Ответ 4

В Unix-системах, которые поддерживают его (не похоже на macOS):

if getent passwd "$username" >/dev/null; then
    printf 'User %s exists\n' "$username"
else
    printf 'User %s does not exist\n' "$username"
fi 

Это имеет то преимущество, что он будет запрашивать любую службу каталогов, которая может быть использована (YP/NIS или LDAP и т.д.) и файл базы данных локального пароля.


Проблема с grep -q "$username" /etc/passwd заключается в том, что она даст ложный результат, когда такого пользователя нет, но что-то еще соответствует шаблону. Это может произойти, если в файле есть частичное или точное совпадение.

Например, в моем passwd файле есть строка с надписью

build:*:21:21:base and xenocara build:/var/empty:/bin/ksh

Это приведет к действительному совпадению таких вещей, как cara и enoc и т.д., даже если в моей системе таких пользователей нет.

Для правильного решения grep вам необходимо правильно проанализировать файл /etc/passwd:

if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
    # found
else
    # not found
fi

... или любой другой аналогичный тест с первым из полей : -delimited.

Ответ 5

Вот ответ в виде примера:

Чтобы убедиться, что регистраторы данных находятся в сети, cron script запускается каждые 15 минут, которые выглядят следующим образом:

#!/bin/bash
#
if ! ping -c 1 SOLAR &>/dev/null
then
  echo "SUBJECT:  SOLAR is not responding to ping" | ssmtp [email protected]
  echo "SOLAR is not responding to ping" | ssmtp [email protected]
else
  echo "SOLAR is up"
fi
#
if ! ping -c 1 OUTSIDE &>/dev/null
then
  echo "SUBJECT:  OUTSIDE is not responding to ping" | ssmtp [email protected]
  echo "OUTSIDE is not responding to ping" | ssmtp [email protected]
else
  echo "OUTSIDE is up"
fi
#

... и так далее для каждого регистратора данных, который вы можете видеть в монтаже на http://www.SDsolarBlog.com/montage


FYI, используя &>/dev/null перенаправляет весь вывод из команды, включая ошибки, на /dev/null

(Условное значение требует только exit status команды ping)

Обратите внимание, что поскольку cron задания выполняются как root, нет необходимости использовать sudo ping в cron script.