Jeg vil have, at brugeren bliver bedt om et spørgsmål og derefter give svaret, som gemmes under en variabel med navnet i, så hvis svaret (som er en fil) eksisterer og er skrivbar, den læser den og griber ting i filen og skriver disse ting til en ny. Hvis filen ikke findes, eller brugeren ikke har tilstrækkelige tilladelser til den fil, bliver der bedt om en advarsel, programmet sover i 3 sekunder, og sløjferne starter igen. Hvorfor fungerer det ikke? Advarslen forsvinder simpelthen ikke, og sløjfen fortsætter heller ikke.
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 fejl.
$a=true
er bare en streng, IKKE en sammenligningshandling. Separer med mellemrum, så sammenligningen finder sted: "$a" = true
.
Med det arbejde vil sløjfen slet ikke indtastes, når du indstiller a=false
på forhånd.
SKAL du endelig komme ind i sløjfen, vil du ikke være i stand til at afslutte, da a
aldrig er indstillet til alt andet end true
, og der er heller ikke en anden udgangsmekanisme (f.eks. break
).
Svar
Som andre har påpeget, har du logiske fejl og syntaksfejl i din kode. ShellCheck-webstedet er godt til at udrydde syntaksfejlene.
Her tager jeg dette. Jeg har to versioner af koden Den første (som jeg foretrækker) har ingen brugerinteraktion, men tager et stinavn på kommandolinjen. Den anden beder interaktivt om et stinavn.
Årsagen til, at den første ikke interaktivt beder om en stienavn er, at det gør ringe forskel, hvis brugeren af scriptet skriver stienavnet på kommandolinjen eller ved dit scripts prompt, og at have scriptprompten til stienavnet diskvalificerer det fra at blive brugt fra f.eks. et cron-job eller et andet sted, hvor der muligvis ikke er knyttet en terminal.
#!/bin/sh pathname=$1 if ! grep "pattern" <$pathname >i2; then echo "Something is wrong" >&2 fi
echo
ovenfor vil være udført når
- filen i
$pathname
ikke kan læses, eller - filen
i2
kan ikke skrives til, eller - mønsteret blev ikke fundet i
$pathname
(dette adskiller sig fra din kode, men se nedenfor) .
Fejlmeddelelsen er skrevet til standardfejl, som det er skik med diagnostiske meddelelser generelt.
Med interaktiv anmodning 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øjfe, der læses fra brugeren og bryder ud af sløjfen, hvis grep
opkaldet gik ok. Hvis grep
mislykkedes af en eller anden grund (en af de tre grunde ovenfor), bliver stienavnet bedt om igen.
Begge kodestykker med en separat test for en læsbar fil (grep
får lov til at mislykkes ved ikke at finde noget eller ikke kan skrive til sin outputfil.
Først den ikke-interaktive version:
#!/bin/sh pathname=$1 if [ ! -r "$pathname" ]; then echo "Something is wrong" >&2 fi grep "pattern" <$pathname >i2
Derefter den interaktive version:
#!/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 version hvor sløjfen kun handler om brugerinput 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 at bruge simpelthen pause for at stoppe uendelig løkke som denne:
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
Ændrede steder har kommentarer med beskrivelse.
grep <$i >i2
i stedet forcat
. Citér også variable udvidelser, hvor det er nødvendigt, som i testen .