Как сделать "если не истинное состояние"?
Я хотел бы иметь echo
команда выполняется, когда cat /etc/passwd | grep "sysa"
- это неправда.
что я делаю не так?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
5 ответов:
попробовать
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,
==,<,>,>=,<=,%
и, возможно, некоторые другие.в этом случае, согласно комментарию Оруэллофила, арифметика оценка может быть урезана еще больше, например
if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....
или
if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....
наконец, есть награда назвал
Useless Use of Cat (UUOC)
. :- ) Некоторые люди будут прыгать вверх и вниз и плакать gothca! Я просто скажу, чтоgrep
может принимать имя файла в своей cmd-строке, так зачем вызывать дополнительные процессы и конструкции труб, когда вам это не нужно? ; -)я надеюсь, что это помогает.
Я думаю, что это можно упростить в:
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; }
что я делаю не так?
$(...)
держит стоимостью, а не статус выхода, поэтому этот подход неверен. Однако, в данном конкретном случае, это действительно работает, потому что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
.нашел другие ответы довольно запутанными, надеюсь, это кому-то поможет.
на системах 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
etc., хотя таких пользователей в моей системе нет.на
grep
решение будет правильным, вам нужно будет правильно разобрать/etc/passwd
file:if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then # found else # not found fi
... или любой другой подобный тест против первых
:
- поля с разделителями.
вот ответ в качестве примера:
для того, чтобы убедиться, что регистраторы данных находятся в сети a
cron
скрипт запускается каждые 15 минут, который выглядит так:#!/bin/bash # if ! ping -c 1 SOLAR &>/dev/null then echo "SUBJECT: SOLAR is not responding to ping" | ssmtp abc@def.com echo "SOLAR is not responding to ping" | ssmtp 4151112222@txt.att.com else echo "SOLAR is up" fi # if ! ping -c 1 OUTSIDE &>/dev/null then echo "SUBJECT: OUTSIDE is not responding to ping" | ssmtp abc@def.com echo "OUTSIDE is not responding to ping" | ssmtp 4151112222@txt.att.com else echo "OUTSIDE is up" fi #
...и так далее для каждого регистратора данных, который вы можете увидеть в монтаже в http://www.SDsolarBlog.com/montage
FYI, используя
&>/dev/null
перенаправляет все выходные данные команды, включая ошибки, на/dev/null
(условный требует только
exit status
на )также FYI, обратите внимание, что с
cron
задания выполняются какroot
нет необходимости использоватьsudo ping
наcron
сценарий.