Jag vill att användaren ska uppmanas med en fråga och sedan ge svaret, vilket kommer att lagras under en variabel med namnet i, sedan om svaret (vilket är en fil) finns och är skrivbar, den läser den och tar tag i saker i filen och skriver dessa saker till en ny. Om filen inte finns eller om användaren inte har tillräckligt med behörighet för den filen, uppmanas en varning, programmet sover i 3 sekunder och looparna startar igen. Varför fungerar inte det? Varningen kommer helt enkelt inte att försvinna, inte heller kommer slingan att fortsätta.
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 syntax och logiska fel.
$a=true
är bara en sträng, INTE en jämförelse. Separera med mellanslag så att jämförelsen kommer att ske: "$a" = true
.
Med det arbetet kommer slingan inte att skrivas in alls, när du ställer in a=false
i förväg.
Ska du äntligen komma in i slingan kommer du inte att kunna avsluta, eftersom a
aldrig är inställt på allt annat än true
, och det finns inte heller någon annan utgångsmekanism (t.ex. break
).
Svar
Som andra har påpekat har du logiska fel och syntaxfel i din kod. ShellCheck-webbplatsen är bra för att rensa bort syntaxfelen.
Här är min åsikt om detta. Jag har två versioner av koden Den första (som jag föredrar) har ingen användarinteraktion men tar ett söknamn på kommandoraden. Den andra ber interaktivt om ett söknamn.
Anledningen till att den första inte interaktivt ber om en sökvägen är att det gör liten skillnad om användaren av skriptet skriver sökvägen på kommandoraden eller vid ditt skriptprompt och att ha skriptprompten för sökvägen diskvalificerar det från att användas från t.ex. ett cron-jobb eller någon annanstans där det inte finns någon ansluten terminal.
#!/bin/sh pathname=$1 if ! grep "pattern" <$pathname >i2; then echo "Something is wrong" >&2 fi
echo
ovan kommer att vara körs när
- filen i
$pathname
inte kan läsas, eller - filen
i2
kan inte skrivas till, eller - mönstret hittades inte i
$pathname
(detta skiljer sig från din kod, men se nedan) .
Felmeddelandet skrivs till standardfel, vilket är vanligt med diagnosmeddelanden i allmänhet.
Med interaktiv uppmaning och fördröjning:
#!/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
Här har vi en oändlig slinga som läser från användaren och bryter ut ur slingan om grep
-samtalet gick ok. Om grep
av någon anledning misslyckades (en av de tre anledningarna ovan) uppmanas sökvägen igen.
Båda koderna med en separat test för en läsbar fil (grep
får misslyckas genom att inte hitta någonting eller inte kunna skriva till sin utdatafil.
Först den icke-interaktiva version:
#!/bin/sh pathname=$1 if [ ! -r "$pathname" ]; then echo "Something is wrong" >&2 fi grep "pattern" <$pathname >i2
Sedan den interaktiva versionen:
#!/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 där slingan endast handlar om användarinmatning och 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
Försök att helt enkelt bryta för att stoppa oändlig slinga så här:
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
Ändrade platser har kommentarer med beskrivning.
grep <$i >i2
snarare äncat
. Citera också variabla utvidgningar där det behövs, som i testet .