Hvordan sløyfer jeg en if-setning i bash?

Jeg vil at brukeren skal bli bedt om et spørsmål og deretter levere svaret, som vil bli lagret under en variabel som heter i, så hvis svaret (som er en fil) eksisterer og er skrivbar, den leser den og tar tak i ting i filen og skriver disse tingene til en ny. Hvis filen ikke eksisterer eller brukeren ikke har nok tillatelser til den filen, blir det bedt om en advarsel, programmet sover i 3 sekunder og sløyfene starter på nytt. Hvorfor fungerer ikke det? Advarselen vil bare ikke forsvinne, og heller ikke sløyfen fortsette.

echo "$(tput setaf 4) Tell me where the file is:" printf "\n" a=false while [ $a=true ]; do read i if [ -w $i ] then cat $i | grep stuff > i2 else a=true printf "Oh something is wrong, try again!" sleep 3 fi done 

Svar

Du har syntaks og logiske feil.

$a=true er bare en streng, IKKE en sammenligningsoperasjon. Separer med mellomrom slik at sammenligningen vil finne sted: "$a" = true.

Med det arbeidet vil ikke sløyfen bli angitt i det hele tatt, når du angir a=false på forhånd.

Bør du endelig komme inn i løkken, vil du ikke kunne gå ut, da a aldri er satt til alt annet enn true, og det er heller ikke gitt en annen utgangsmekanisme (f.eks. break).

Svar

Som andre har påpekt, har du logiske feil og syntaksfeil i koden din. ShellCheck-siden er bra for å lukke ut syntaksfeilene.

Her tar jeg dette. Jeg har to versjoner av koden Den første (som jeg foretrekker) har ingen brukerinteraksjon, men tar et banenavn på kommandolinjen. Den andre ber interaktivt om et banenavn.

Årsaken til at den første ikke interaktivt ber om en banenavn er at det gjør liten forskjell hvis brukeren av skriptet skriver stinavnet på kommandolinjen eller ved skriptets ledetekst, og å ha manusforespørselen for stienavnet diskvalifiserer det fra å brukes en cron-jobb eller hvor som helst der det ikke er tilknyttet en terminal.

#!/bin/sh pathname=$1 if ! grep "pattern" <$pathname >i2; then echo "Something is wrong" >&2 fi 

echo ovenfor vil være utført når

  • filen i $pathname ikke kan leses, eller
  • filen i2 kan ikke skrives til, eller
  • mønsteret ble ikke funnet i $pathname (dette er forskjellig fra koden din, men se nedenfor) .

Feilmeldingen er skrevet som standardfeil, slik det er vanlig med diagnostiske meldinger generelt.

Med interaktiv forespørsel og forsinkelse:

#!/bin/bash while true; do read -r -p "Pathname: " pathname if grep "pattern" <$pathname >i2; then break fi echo "Something is wrong" >&2 sleep 3 done 

Her har vi en uendelig sløyfe som leser fra brukeren og bryter ut av sløyfen hvis grep samtalen gikk ok. Hvis grep mislyktes av en eller annen grunn (en av de tre grunnene ovenfor), blir stienavnet bedt om igjen.


Begge kodestykkene med et eget test for en lesbar fil (grep får lov til å mislykkes ved ikke å finne noe eller ikke kan skrive til utdatafilen.

Først den ikke-interaktive versjon:

#!/bin/sh pathname=$1 if [ ! -r "$pathname" ]; then echo "Something is wrong" >&2 fi grep "pattern" <$pathname >i2 

Deretter den interaktive versjonen:

#!/bin/bash while true; do read -r -p "Pathname: " pathname if [ -r "$pathname" ]; then grep "pattern" <$pathname >i2 break fi echo "Something is wrong" >&2 sleep 3 done 

Eller en interaktiv versjon der sløyfen kun handler om brukerinngang og validering:

#!/bin/bash while true; do read -r -p "Pathname: " pathname [ -r "$pathname" ] && break echo "Something is wrong" >&2 sleep 3 done grep "pattern" <$pathname >i2 

Svar

Prøv å bruke bare pause for å stoppe uendelig sløyfe som dette:

echo "$(tput setaf 4) Tell me where the file is:" echo # This prints empty line like printf "\n" while true; do # "while true" or "while :" is infinite loop read i if [ -r $i ] # You probably mean -r (readable) and not -w (writable) then cat $i | grep stuff > i2 break # "break" ends loop else echo -n "Oh something is wrong, try again!" # "echo -n" means print without newline character sleep 3 fi done 

Endrede steder har kommentarer med beskrivelse.

Kommentarer

  • grep <$i >i2 i stedet for cat. Sitere også variabel utvidelser der det er nødvendig, som i testen .

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *