Chci, aby byl uživatel vyzván k zadání otázky a zadání odpovědi, která bude uložena pod proměnnou s názvem i, pak pokud odpověď (která je soubor) existuje a je zapisovatelný, čte jej, řeší věci v souboru a zapisuje je do nového. Pokud soubor neexistuje nebo uživatel nemá nad tímto souborem dostatečná oprávnění, zobrazí se varování, program usne po dobu 3 sekund a smyčky se spustí znovu. Proč to nefunguje? Varování prostě nezmizí, ani smyčka nebude pokračovat.
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
Odpovědět
Máte syntaxi a logické chyby.
$a=true
je pouze řetězec, NENÍ operace porovnání. Oddělte je mezerami, aby došlo k porovnání: "$a" = true
.
S touto prací nebude smyčka vůbec zadána, jak nastavíte a=false
předem.
MUSÍTE se konečně dostat do smyčky, nebudete moci opustit, protože a
nikdy nastaveno na cokoli jiného než true
, není k dispozici ani jiný výstupní mechanismus (např. break
).
Odpověď
Jak již zdůraznili ostatní, ve vašem kódu jsou logické chyby a chyby syntaxe. Web ShellCheck je vhodný pro odstraňování syntaktických chyb.
Tady je můj názor. Mám dvě verze kódu . První (kterou preferuji) nemá žádnou interakci s uživatelem, ale vezme si cestu na příkazovém řádku. Druhý si interaktivně vyžádá název cesty.
Důvod, proč první interaktivně nevyzve k zadání cesta je v tom, že je malý rozdíl, pokud uživatel skriptu napíše cestu na příkazový řádek nebo na výzvu vašeho skriptu a výzva skriptu pro cestu jej znemožňuje použití např. úloha cron nebo kdekoli jinde, kde nemusí být připojen terminál.
#!/bin/sh pathname=$1 if ! grep "pattern" <$pathname >i2; then echo "Something is wrong" >&2 fi
echo
výše bude provedeno, když
- soubor v
$pathname
nelze číst, nebo - soubor
i2
nelze „zapsat, nebo - vzor nebyl v
$pathname
nalezen (liší se od vašeho kódu, ale viz níže) .
Chybová zpráva se zapíše na standardní chybu, jak je zvykem u diagnostických zpráv obecně.
S interaktivní výzvou a zpožděním:
#!/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
Zde máme nekonečnou smyčku, která čte od uživatele a vyloučí se ze smyčky, pokud volání grep
proběhlo v pořádku. Pokud grep
selhal z jakéhokoli důvodu (jeden ze tří výše uvedených důvodů), je cesta znovu vyzvána.
Obě části kódu se samostatným otestujte čitelný soubor (grep
může selhat tím, že nic nenalezne nebo nebude schopen zapisovat do svého výstupního souboru.
Nejprve neinteraktivní verze:
#!/bin/sh pathname=$1 if [ ! -r "$pathname" ]; then echo "Something is wrong" >&2 fi grep "pattern" <$pathname >i2
Pak interaktivní verze:
#!/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
Nebo interaktivní verze kde se smyčka zabývá pouze vstupem a ověřením uživatele:
#!/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
odpověď
Zkuste zastavit nekonečnou smyčku takto jednoduše pomocí break:
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
Upravená místa obsahují komentáře s popisem.
grep <$i >i2
spíše nežcat
. V případě potřeby uveďte také variabilní rozšíření, například v testu .