Ich möchte den echo
Befehl 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 echo
Befehl 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
grep
Gibt zurück, true
wenn das Suchziel gefunden wird und false
wenn 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 -c
Option (count) verwenden, um zu grep und dann zu tun, if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then
was 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 grep
ein 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 -v
wobei -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>&2
am Ende Ihres echo
Ausdrucks stderr
?
!: not found
'grep
diese verwenden. -q
unterdrü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 sysa
es gedruckt wird, wodurch die Testaussage wahr wird. Allerdings if ! [ $(true) ]; then echo false; fi
drucken würde immer , false
weil der true
Befehl 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/passwd
ist, 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 passwd
Datei 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 cara
und enoc
usw. hervorrufen , obwohl es auf meinem System keine solchen Benutzer gibt.
Damit eine grep
Lösung korrekt ist, müssen Sie die /etc/passwd
Datei 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.
bash
in diesem Fall wahrscheinlich nicht ausgeführt .
Hier ist eine Antwort als Beispiel:
Um sicherzustellen, dass Datenlogger online sind, wird cron
alle 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/null
Leitet alle Ausgaben des Befehls, einschließlich Fehler, an weiter/dev/null
(Die Bedingung erfordert nur exit status
den ping
Befehl)
Auch FYI, beachten Sie, dass seit cron
Aufträge ausführen als root
es keine Notwendigkeit zu verwenden , ist sudo ping
in einem cron
Skript.
!
nicht in den Klammern sein? dh[ ! EXPR ]