Binær operatør forventet – siterer spørsmål for skallskript args

Jeg har et spørsmål om hvordan jeg legger til argumenter når jeg kjører et skallskript.

Jeg har et enkelt skript som hjelper meg å blokkere ip-områder:

~/block_ip.sh:

if [ ! $3 ] then echo "usage ~/block_ip.sh (DROP/ACCEPT) "0.0.0.0" "amsterdam"" exit 1 fi echo "adding $3" sudo iptables -I INPUT -s $2 -j $1 -m comment --comment "$3" 

Hvis jeg utfører dette uten argumenter, er utdataene som forventet:

~$ ./block_ip.sh usage ~/block_ip.sh (DROP/ACCEPT) "0.0.0.0" "amsterdam" 

Imidlertid synes mellomrommene å være årsaken til uventet utdata fra «forventet binær operatør» :

~$ ./block_ip.sh DROP "1.0.0.0/8" "south brisbane qld" ./block_ip.sh: line 1: [: brisbane: binary operator expected adding south brisbane au 

Men så legger den til til tross for uventet utdata:

Chain INPUT (policy ACCEPT) num target prot opt source destination 1 DROP all -- 1.0.0.0/8 anywhere /* south brisbane au */ 

Hvis dette er et siteringsproblem, hvordan lager jeg argumentene (uten å bruke tilbakeslag for å unnslippe mellomromene)? Selvfølgelig forventer jeg at jeg kanskje trenger en endring til skriptet, er det også en akseptabel løsning.

Kommentarer

  • Hvis målet ditt er å teste $3 er bare for å være sikker på at det er tre parametere, da du kan bruke den enklere $# skallvariabelen, som inneholder antall parametere, f.eks. if [ $# -ne 3 ].

Svar

Jepp, det er et sitat problem: [ ! $3 ] utvides til [ ! south brisbane qld ] (fire argumenter mellom [ og ]). Og når den ser fire argumenter, med den første forventer en !, [ å se noe som [ ! arg1 op arg2 ] der op er en binær operator. (dette er igjen en av de tingene som er forskjellige mellom [ .. ] og [[ .. ]]; se denne Q og også denne Q )

brisbane er ikke en gyldig operatør, så den klager og returnerer 2, som er falske, så utsagnene i if kjøres ikke. For å se forskjellen mellom en feil og en vanlig sviktende test, må du eksplisitt teste returverdien mot 2.

På den annen side, hvis $3 er tom, så blir testen til [ ! ], en test med ett argument som sjekker om det eneste argumentet er ikke-fritt (det er, det er entegnsstrengen !). I så fall fungerer det som ment, men kanskje ikke av den grunnen du forventer.


Du vil ha [ ! "$3" ] eller [ -z "$3" ] for å beholde strengen som ett argument for [.

Selvfølgelig kan du også invertere følelsen av testen og gjøre faktisk arbeid i if, slik at en feil i testen ville unngå å kjøre hovedkommandoene. Men det ville gjøre kodestrukturen litt mer uklar.

Kommentarer

  • hyggelig – så grunnen til at det fungerer da er at selv om det feiler, er $ 3 ikke ' t tomt så det består! -testen, og så har jeg den sitert i iptables -kommandoen, slik at utvidelsen til å inkludere mellomrom håndteres allerede – er det riktig?
  • og de ' Jeg vil også sitere parametrene i iptables-linjen
  • @WEBjuju, ah ja, jeg mente å skrive om det, redigerte hvorfor det fungerer. Og ja,du hadde anførselstegnene i iptables -kommandoen, så der fungerer det fint.
  • @ilkkachu gotcha, ja, det virker dumt på min side. på en eller annen måte visste jeg det ubevisst, men kunne ikke ' ikke bringe frem kunnskapen til en fungerende løsning. Jeg har på en eller annen måte rotet meg gjennom uten å kjenne denne grunnleggende leietakeren til nå, men jeg rettferdig jevnet meg opp. mye takk!

Legg igjen en kommentar

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