Hoe maak je een “indien niet waar”?

Ik wil graag dat de opdracht echowordt 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

grepretourneert trueals het zoekdoel wordt gevonden, en falseals dat niet het geval is.

Dus NIET false== true.

ifevaluatie 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 ] ; thenwat 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 grepeen 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 sysawordt afgedrukt, waardoor de testverklaring uitkomt. Echter, if ! [ $(true) ]; then echo false; fizou altijd falseafdrukken omdat de opdracht trueniets 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/passwdis 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 caraen enocenz., ook al zijn er geen dergelijke gebruikers op mijn systeem.

Om een grep-oplossing correct te laten zijn, moet u het bestand /etc/passwdcorrect 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/nullleidt alle uitvoer van de opdracht, inclusief fouten, om naar /dev/null

(De voorwaardelijke vereist alleen de exit statusvan het pingcommando)

Ook ter informatie: aangezien cron-taken als rootworden uitgevoerd, is het niet nodig om sudo pingte gebruiken in een cron-script.

Other episodes