Ik wil graag dat de opdracht echo
wordt uitgevoerd wanneer cat /etc/passwd | grep "sysa"
is niet waar.
Wat doe ik verkeerd?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
Antwoord 1, autoriteit 100%
probeer
if ! grep -q sysa /etc/passwd ; then
grep
retourneert true
als het zoekdoel wordt gevonden, en false
als dat niet het geval is.
Dus NIET false
== true
.
if
evaluatie in shells is ontworpen om zeer flexibel te zijn, en vereist vaak geen reeks commando’s (zoals je hebt geschreven).
Ook als je naar je code kijkt zoals deze is, is je gebruik van de $( ... )
vorm van cmd-substitutie te prijzen, maar denk eens na over wat er uit het proces komt. Probeer echo $(cat /etc/passwd | grep "sysa")
om te zien wat ik bedoel. U kunt verder gaan door de optie -c
(count) te gebruiken om grep te gebruiken en vervolgens if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then
wat werkt maar nogal ouderwets is.
MAAR, je zou de nieuwste shell-functies (rekenkundige evaluatie) kunnen gebruiken, zoals
if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`
wat u ook het voordeel geeft van het gebruik van de op c-lang gebaseerde vergelijkingsoperatoren, ==,<,>,>=,<=,%
en misschien een paar andere.
In dit geval kan, volgens een opmerking van Orwellophile, de rekenkundige evaluatie nog verder worden teruggebracht, zoals
if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....
OF
if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....
Ten slotte is er een awardgenaamd de Useless Use of Cat (UUOC)
. 🙂 Sommige mensen zullen op en neer springen en gothca huilen! Ik zeg alleen dat grep
een bestandsnaam kan aannemen op de cmd-regel, dus waarom zou je extra processen en pijpconstructies aanroepen als dat niet nodig is? 😉
Ik hoop dat dit helpt.
Antwoord 2, autoriteit 7%
Ik denk dat het kan worden vereenvoudigd tot:
grep sysa /etc/passwd || {
echo "ERROR - The user sysa could not be looked up"
exit 2
}
of in een enkele opdrachtregel
$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }
Antwoord 3, autoriteit 2%
Wat doe ik verkeerd?
$(...)
heeft de waarde, niet de exit-status, daarom is deze benadering verkeerd. In dit specifieke geval werkt het echter wel omdat sysa
wordt afgedrukt, waardoor de testverklaring uitkomt. Echter, if ! [ $(true) ]; then echo false; fi
zou altijd false
afdrukken omdat de opdracht true
niets naar stdout schrijft (ook al is de afsluitcode 0). Daarom moet het opnieuw worden geformuleerd in if ! grep ...; then
.
Een alternatief zou zijn cat /etc/passwd | grep "sysa" || echo error
. Bewerken: zoals Alex opmerkte, kat is hier nutteloos: grep "sysa" /etc/passwd || echo error
.
Vind de andere antwoorden nogal verwarrend, ik hoop dat dit iemand helpt.
Antwoord 4, autoriteit 2%
Deze
if [[ ! $(cat /etc/passwd | grep "sysa") ]]
Then echo " something"
exit 2
fi
Antwoord 5
Op Unix-systemen die dit ondersteunen (niet macOS lijkt het):
if getent passwd "$username" >/dev/null; then
printf 'User %s exists\n' "$username"
else
printf 'User %s does not exist\n' "$username"
fi
Dit heeft het voordeel dat het elke directoryservice die in gebruik is (YP/NIS of LDAP enz.) en het lokale wachtwoorddatabasebestand zal opvragen.
Het probleem met grep -q "$username" /etc/passwd
is dat het een false positive zal geven als er geen dergelijke gebruiker is, maar iets anders komt overeen met het patroon. Dit kan gebeuren als er ergens anders in het bestand een gedeeltelijke of exacte overeenkomst is.
In mijn passwd
-bestand staat bijvoorbeeld een regel met de tekst
build:*:21:21:base and xenocara build:/var/empty:/bin/ksh
Dit zou een geldige overeenkomst opleveren voor zaken als cara
en enoc
enz., ook al zijn er geen dergelijke gebruikers op mijn systeem.
Om een grep
-oplossing correct te laten zijn, moet u het bestand /etc/passwd
correct ontleden:
if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
# found
else
# not found
fi
… of een andere vergelijkbare test tegen de eerste van de :
-gescheiden velden.
Antwoord 6
Hier is een antwoord bij wijze van voorbeeld:
Om ervoor te zorgen dat dataloggers online zijn, wordt elke 15 minuten een cron
-script uitgevoerd dat er als volgt uitziet:
#!/bin/bash
#
if ! ping -c 1 SOLAR &>/dev/null
then
echo "SUBJECT: SOLAR is not responding to ping" | ssmtp [email protected]
echo "SOLAR is not responding to ping" | ssmtp [email protected]
else
echo "SOLAR is up"
fi
#
if ! ping -c 1 OUTSIDE &>/dev/null
then
echo "SUBJECT: OUTSIDE is not responding to ping" | ssmtp [email protected]
echo "OUTSIDE is not responding to ping" | ssmtp [email protected]
else
echo "OUTSIDE is up"
fi
#
…en ga zo maar door voor elke datalogger die je kunt zien in de montage
op http://www.SDsolarBlog.com/montage
Ter info, het gebruik van &>/dev/null
leidt alle uitvoer van de opdracht, inclusief fouten, om naar /dev/null
(De voorwaardelijke vereist alleen de exit status
van het ping
commando)
Ook ter informatie: aangezien cron
-taken als root
worden uitgevoerd, is het niet nodig om sudo ping
te gebruiken in een cron
-script.