Я хотів би, щоб 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
Я хотів би, щоб 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
Відповіді:
спробуйте
if ! grep -q sysa /etc/passwd ; then
grep
повертається, true
якщо знаходить пошукову ціль, а false
якщо її немає.
Так НЕ false
== true
.
if
Оцінка в оболонках розроблена як дуже гнучка, і багато разів не вимагає ланцюжок команд (як ви написали).
Крім того, дивлячись на свій код таким, який ви маєте, $( ... )
слід похвалитись використанням форми cmd-substitution, але подумайте про те, що виходить із процесу. Спробуйте echo $(cat /etc/passwd | grep "sysa")
зрозуміти, що я маю на увазі. Ви можете взяти це далі, скориставшись -c
(count) опцією, щоб виграти, а потім зробити, 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)
. :-) Деякі люди будуть стрибати вгору-вниз і плакати готці! Я просто скажу, що grep
може приймати ім'я файлу у його cmd-рядку, тож навіщо викликати додаткові процеси та конструкції труб, коли цього не потрібно? ;-)
Я сподіваюся, що це допомагає.
grep "^$user:" /etc/passwd
був би більш правильним способом пошуку / etc / passwd інцидентно - grep -v
куди -v перетворює пошук, якщо хотів щоб уникнути безладу ||
(( $( cat file | grep regex | wc -l ) ? 0 : 1 ))
Я думаю, що це можна спростити в:
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; }
1>&2
в кінці вашого echo
до друку stderr
?
!: not found
'grep
подібного. -q
пригнічує вихід.
Що я роблю неправильно?
$(...)
має значення , а не статус виходу, тому такий підхід є неправильним. Однак у цьому конкретному випадку це дійсно спрацьовує, тому що 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
т.д., навіть якщо немає таких користувачів на моїй системі.
Щоб grep
рішення було правильним, вам потрібно буде правильно розібрати /etc/passwd
файл:
if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
# found
else
# not found
fi
... або будь-який інший подібний тест щодо першого з :
розділених полів.
bash
в цьому випадку.
Ось відповідь на прикладі:
Щоб переконатися, що реєстратори даних є в Інтернеті, 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
від ping
команди)
Також FYI зауважте, що оскільки cron
завдання виконуються, так як root
немає необхідності використовувати sudo ping
в cron
сценарії.
!
не повинно бути всередині дужок? тобто[ ! EXPR ]