Ich möchte den echoBefehl ausführen lassen, wenn er cat /etc/passwd | grep "sysa"nicht wahr ist.
Was mache ich falsch?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
Ich möchte den echoBefehl ausführen lassen, wenn er cat /etc/passwd | grep "sysa"nicht wahr ist.
Was mache ich falsch?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
Antworten:
Versuchen
if ! grep -q sysa /etc/passwd ; then
grepGibt zurück, truewenn das Suchziel gefunden wird und falsewenn dies nicht der Fall ist.
Also NICHT false== true.
if Die Auswertung in Shells ist sehr flexibel und erfordert häufig keine Befehlsketten (wie Sie geschrieben haben).
Wenn Sie Ihren Code so betrachten, wie er ist, ist Ihre Verwendung der $( ... )Form der cmd-Substitution zu empfehlen, aber denken Sie darüber nach, was aus dem Prozess herauskommt. Versuche echo $(cat /etc/passwd | grep "sysa")zu sehen, was ich meine. Sie können das weiterführen, indem Sie die -cOption (count) verwenden, um zu grep und dann zu tun, if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; thenwas funktioniert, aber eher altmodisch ist.
ABER Sie könnten die neuesten Shell-Funktionen (arithmetische Auswertung) wie verwenden
if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`
Dies bietet Ihnen auch den Vorteil, die c-lang-basierten Vergleichsoperatoren ==,<,>,>=,<=,%und möglicherweise einige andere zu verwenden.
In diesem Fall kann laut einem Kommentar von Orwellophile die arithmetische Bewertung noch weiter reduziert werden, wie z
if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....
ODER
if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....
Schließlich gibt es eine Auszeichnung namens Useless Use of Cat (UUOC). :-) Manche Leute springen auf und ab und weinen Gothca! Ich sage nur, dass grepein Dateiname in die cmd-Zeile aufgenommen werden kann. Warum also zusätzliche Prozesse und Pipe-Konstruktionen aufrufen, wenn dies nicht erforderlich ist? ;-);
Ich hoffe das hilft.
grep "^$user:" /etc/passwd wäre übrigens die korrektere Art, / etc / passwd zu suchen - grep -vwobei -v die Suche umkehrt, wenn Sie möchten um das Durcheinander von || zu vermeiden
(( $( cat file | grep regex | wc -l ) ? 0 : 1 ))
Ich denke, es kann vereinfacht werden in:
grep sysa /etc/passwd || {
echo "ERROR - The user sysa could not be looked up"
exit 2
}
oder in einer einzelnen Befehlszeile
$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }
1>&2am Ende Ihres echoAusdrucks stderr?
!: not found
'grepdiese verwenden. -qunterdrückt die Ausgabe.
Was mache ich falsch?
$(...)hält den Wert , nicht den Exit-Status, deshalb ist dieser Ansatz falsch. In diesem speziellen Fall funktioniert es jedoch tatsächlich, da sysaes gedruckt wird, wodurch die Testaussage wahr wird. Allerdings if ! [ $(true) ]; then echo false; fidrucken würde immer , falseweil der trueBefehl keine Schreib etwas zu stdout tut (auch wenn der Exit - Code 0). Deshalb muss es umformuliert werden if ! grep ...; then.
Eine Alternative wäre cat /etc/passwd | grep "sysa" || echo error. Edit: Wie Alex betonte, ist Katze hier nutzlos : grep "sysa" /etc/passwd || echo error.
Fanden die anderen Antworten eher verwirrend, hoffe das hilft jemandem.
Auf Unix-Systemen, die dies unterstützen (anscheinend nicht unter macOS):
if getent passwd "$username" >/dev/null; then
printf 'User %s exists\n' "$username"
else
printf 'User %s does not exist\n' "$username"
fi
Dies hat den Vorteil, dass alle möglicherweise verwendeten Verzeichnisdienste (YP / NIS oder LDAP usw.) und die lokale Kennwortdatenbankdatei abgefragt werden.
Das Problem dabei grep -q "$username" /etc/passwdist, dass es ein falsches Positiv gibt, wenn es keinen solchen Benutzer gibt, aber etwas anderes dem Muster entspricht. Dies kann passieren, wenn an einer anderen Stelle in der Datei eine teilweise oder genaue Übereinstimmung vorliegt.
In meiner passwdDatei steht beispielsweise eine Zeile mit der Aufschrift
build:*:21:21:base and xenocara build:/var/empty:/bin/ksh
Dies würde eine gültige Übereinstimmung für Dinge wie caraund enocusw. hervorrufen , obwohl es auf meinem System keine solchen Benutzer gibt.
Damit eine grepLösung korrekt ist, müssen Sie die /etc/passwdDatei ordnungsgemäß analysieren :
if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
# found
else
# not found
fi
... oder einen ähnlichen Test gegen das erste der :begrenzten Felder.
bashin diesem Fall wahrscheinlich nicht ausgeführt .
Hier ist eine Antwort als Beispiel:
Um sicherzustellen, dass Datenlogger online sind, wird cronalle 15 Minuten ein Skript ausgeführt, das folgendermaßen aussieht:
#!/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
#
... und so weiter für jeden Datenlogger, den Sie in der Montage unter http://www.SDsolarBlog.com/montage sehen können
Zu Ihrer Information: &>/dev/nullLeitet alle Ausgaben des Befehls, einschließlich Fehler, an weiter/dev/null
(Die Bedingung erfordert nur exit statusden pingBefehl)
Auch FYI, beachten Sie, dass seit cronAufträge ausführen als rootes keine Notwendigkeit zu verwenden , ist sudo pingin einem cronSkript.
!nicht in den Klammern sein? dh[ ! EXPR ]