Chciałbym, aby echo
polecenie zostało wykonane, gdy cat /etc/passwd | grep "sysa"
nie jest prawdziwe.
Co ja robię źle?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
Chciałbym, aby echo
polecenie zostało wykonane, gdy cat /etc/passwd | grep "sysa"
nie jest prawdziwe.
Co ja robię źle?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
Odpowiedzi:
próbować
if ! grep -q sysa /etc/passwd ; then
grep
zwraca, true
jeśli znajdzie cel wyszukiwania, a false
jeśli nie.
Więc NIE false
== true
.
if
Ocena w powłokach ma być bardzo elastyczna i wiele razy nie wymaga łańcuchów poleceń (jak napisałeś).
Patrząc na kod $( ... )
w obecnej postaci, należy pochwalić użycie metody podstawienia cmd, ale zastanów się, co z tego wynika. Spróbuj echo $(cat /etc/passwd | grep "sysa")
zobaczyć, co mam na myśli. Możesz pójść dalej, używając opcji -c
(count), aby grep, a następnie zrobić to, if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then
co działa, ale jest to raczej stara szkoła.
ALE, możesz użyć najnowszych funkcji powłoki (ocena arytmetyczna), takich jak
if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`
co daje również korzyść z używania operatorów porównania opartych na c-lang ==,<,>,>=,<=,%
i kilku innych.
W tym przypadku, według komentarza Orwellophile'a, ocena arytmetyczna może być jeszcze bardziej ograniczona
if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....
LUB
if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....
Wreszcie jest nagroda o nazwie Useless Use of Cat (UUOC)
. :-) Niektórzy skaczą w górę i w dół i płaczą gothca! Powiem tylko, że grep
może przyjmować nazwę pliku na linii cmd, więc po co wywoływać dodatkowe procesy i konstrukcje rur, kiedy nie musisz? ;-)
Mam nadzieję, że to pomoże.
grep "^$user:" /etc/passwd
byłby bardziej prawidłowym sposobem wyszukiwania / etc / passwd przypadkowo - grep -v
gdzie -v odwraca wyszukiwanie, jeśli chcesz aby uniknąć bałaganu ||
(( $( cat file | grep regex | wc -l ) ? 0 : 1 ))
Myślę, że można to uprościć w:
grep sysa /etc/passwd || {
echo "ERROR - The user sysa could not be looked up"
exit 2
}
lub w jednym wierszu poleceń
$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }
1>&2
na końcu echo
do drukowania stderr
?
!: not found
'grep
tego w ten sposób. -q
tłumi wydajność.
Co ja robię źle?
$(...)
zawiera wartość , a nie status wyjścia, dlatego takie podejście jest błędne. Jednak w tym konkretnym przypadku to rzeczywiście działa, ponieważ sysa
zostanie wydrukowane, dzięki czemu instrukcja testowa się spełni. Jednak if ! [ $(true) ]; then echo false; fi
zawsze wydrukować false
, ponieważ true
komenda nie pisze nic na standardowe wyjście (mimo że kod wyjścia jest równy 0). Dlatego należy go przeformułować if ! grep ...; then
.
Alternatywą byłoby cat /etc/passwd | grep "sysa" || echo error
. Edit: Jak Alex wskazał, kot ma sensu tutaj : grep "sysa" /etc/passwd || echo error
.
Znalazłem inne odpowiedzi raczej mylące, mam nadzieję, że to komuś pomoże.
W systemach Unix, które go obsługują (wydaje się, że nie macOS):
if getent passwd "$username" >/dev/null; then
printf 'User %s exists\n' "$username"
else
printf 'User %s does not exist\n' "$username"
fi
Ma to tę zaletę, że wysyła zapytanie do dowolnej usługi katalogowej, która może być używana (YP / NIS lub LDAP itp.) Oraz do lokalnego pliku bazy danych haseł.
Problem grep -q "$username" /etc/passwd
polega na tym, że daje fałszywie dodatni wynik, gdy nie ma takiego użytkownika, ale coś innego pasuje do wzorca. Może się to zdarzyć, jeśli w pliku znajduje się częściowe lub dokładne dopasowanie.
Na przykład w moim passwd
pliku jest napis:
build:*:21:21:base and xenocara build:/var/empty:/bin/ksh
W ten sposób sprowokować ważny mecz na rzeczy, jak cara
i enoc
itd., Mimo że nie ma takich użytkowników na moim systemie.
Aby grep
rozwiązanie było poprawne, musisz poprawnie przeanalizować /etc/passwd
plik:
if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
# found
else
# not found
fi
... lub jakikolwiek inny podobny test w stosunku do pierwszego z :
-delimowanych pól.
bash
W tym przypadku Twój kod prawdopodobnie nie jest wykonywany .
Oto przykładowa odpowiedź:
Aby upewnić się, że rejestratory danych są w trybie online, cron
skrypt uruchamia się co 15 minut i wygląda następująco:
#!/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
#
... i tak dalej dla każdego rejestratora danych, który można zobaczyć w montażu na stronie http://www.SDsolarBlog.com/montage
FYI, używając &>/dev/null
przekierowuje wszystkie dane wyjściowe polecenia, w tym błędy, do/dev/null
(Warunkowe wymaga tylko exit status
z ping
poleceniem)
Również FYI, zauważ, że ponieważ cron
zadania działają, ponieważ root
nie ma potrzeby używania sudo ping
w cron
skrypcie.
!
nie powinno być w nawiasach? tj.[ ! EXPR ]