Kuinka voin luoda if-lauseen silmukan bashissa?

Haluan, että käyttäjältä kysytään kysymystä ja toimitetaan sitten vastaus, joka tallennetaan muuttujaan i, sitten jos vastaus (mikä on tiedosto) on olemassa ja kirjoitettavissa, se lukee sen, tarttuu tiedostossa oleviin asioihin ja kirjoittaa ne uuteen. Jos tiedostoa ei ole olemassa tai käyttäjällä ei ole tarpeeksi käyttöoikeuksia kyseiseen tiedostoon, saat varoituksen, ohjelma nukkuu 3 sekuntia ja silmukat alkavat uudelleen. Miksi se ei toimi? Varoitus ei yksinkertaisesti poistu, eikä silmukka jatku.

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 

Vastaa

Sinulla on syntaksia ja loogisia virheitä.

$a=true on vain merkkijono, EI vertailutoiminto. Erota välilyönneillä, jotta vertailu tapahtuu: "$a" = true.

Kun työskentelet, silmukkaa ei syötetä ollenkaan, kun asetat a=false etukäteen.

PITÄÄS sinun päästä lopulta silmukkaan, et voi poistua, koska a ei ole koskaan asetettu mihinkään muuhun kuin true, eikä muuta poistumismekanismia (esim. break) ole annettu.

Vastaus

Kuten muut ovat huomauttaneet, koodissasi on loogisia virheitä ja syntaksivirheitä. ShellCheck-sivusto on hyvä kitkemään syntaksivirheet.

Tässä on tämä. Minulla on kaksi versiota koodista Ensimmäisellä (mieluummin) ei ole käyttäjän vuorovaikutusta, mutta se vie polun komentoriville. Toinen kysyy vuorovaikutteisesti polunimeä.

Syy, että ensimmäinen ei pyydä vuorovaikutteisesti polun nimi on se, että sillä ei ole juurikaan eroa, jos komentosarjan käyttäjä kirjoittaa polun nimen komentoriville tai komentosarjosi kehotteeseen, ja jos polun nimen komentokehotteella on komento, se estää sen käyttämästä esim. cron-työ tai muualla, johon ei ole liitetty päätelaitetta.

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

Yllä oleva echo suoritetaan, kun

  • tiedostoa $pathname ei voida lukea, tai
  • tiedostoa i2 -tiedostoon ei voida kirjoittaa, tai
  • mallia ei löytynyt kohdasta $pathname (tämä eroaa koodistasi, mutta katso alla) .

Virhesanoma kirjoitetaan vakiovirheeksi, kuten diagnostiikkaviestien tapaan yleensä.

Interaktiivisella kehotuksella ja viiveellä:

#!/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 

Tässä meillä on ääretön silmukka, joka lukee käyttäjältä ja katkeaa silmukasta, jos grep -kutsu meni ok. Jos grep epäonnistui jostain syystä (yksi kolmesta yllä olevasta syystä), polun nimi kysytään uudelleen.


Molemmat koodikappaleet erillisellä testi luettavalle tiedostolle (grep saa epäonnistua, jos et löydä mitään tai ei voi kirjoittaa sen lähtötiedostoon.

Ensin ei-vuorovaikutteinen versio:

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

Sitten vuorovaikutteinen versio:

#!/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 

Tai interaktiivinen versio missä silmukka käsittelee vain käyttäjän syötteitä ja tarkistuksia:

#!/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 

vastaus

Yritä lopettaa ääretön silmukka yksinkertaisesti break-toiminnolla seuraavasti:

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 

Muokatuissa paikoissa on kommentteja kuvauksen kanssa.

Kommentit

  • grep <$i >i2 eikä cat. Lainaa myös muuttujien laajennuksia tarvittaessa, kuten testissä .

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *