Binär operatör förväntas – citerar fråga för skalskript args

Jag har en fråga om hur jag lägger till argument när jag kör ett skalskript.

Jag har ett enkelt skript som hjälper mig att blockera IP-intervall:

~/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" 

Om jag utför detta utan argument är utdata som förväntat:

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

Emellertid verkar utrymmena vara orsaken till oväntad utdata från ”förväntad 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 sedan lägger den till trots den oväntade utdata:

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

Om det här är ett citatfråga, hur formar jag argumenten (utan att använda bakåtvända snedstreck för att undkomma mellanslag)? till manuset är det också en acceptabel lösning.

Kommentarer

  • Om ditt mål att testa $3 är bara för att vara säker på att det finns tre parametrar, då Du kan använda den enklare $# skalvariabeln, som innehåller antalet parametrar, t.ex. if [ $# -ne 3 ].

Svar

Japp, det ”citerar issue: [ ! $3 ] expanderar till [ ! south brisbane qld ] (fyra argument mellan [ och ]). Och när den ser fyra argument, med den första, !, [ förväntar sig att se något som [ ! arg1 op arg2 ] där op är en binär operatör. (detta är återigen en av de saker som skiljer sig mellan [ .. ] och [[ .. ]]; se denna fråga och även denna fråga )

brisbane är inte en giltig operatör, så den klagar och returnerar 2, vilket är falskt så uttalandena i if körs inte. För att berätta skillnaden mellan ett fel och ett vanligt test som misslyckas, måste du uttryckligen testa returvärdet mot 2.

Å andra sidan, om $3 är tomt, då blir testet [ ! ], ett test med ett argument som kontrollerar om det enda argumentet är ogiltigt (det är, det är en teckensträng !). I så fall fungerar det som avsett, men kanske inte av den anledningen du skulle förvänta dig.


Du vill ha [ ! "$3" ] eller [ -z "$3" ] för att behålla strängen som ett argument för [.

Naturligtvis kan du också invertera testets känsla och göra faktiskt arbete i if, så att ett fel i testet skulle undvika att köra huvudkommandona. Men det skulle göra kodstrukturen lite mer oklar.

Kommentarer

  • trevligt – så anledningen till att det fungerar då är att även om det går fel är $ 3 inte ' t tomt så det klarar! testet och sedan har jag det citerat i kommandot iptables så att dess expansion till att inkludera mellanslag hanteras redan – stämmer det?
  • och de ' Jag vill också citera parametrarna i iptables-raden
  • @WEBjuju, ah ja, jag menade att skriva om det, redigerade varför det fungerar. Och ja,du hade citaten i kommandot iptables så där fungerar det bra.
  • @ilkkachu gotcha, ja, det verkar dumt i mitt slut. på något sätt visste jag det omedvetet men kunde inte ' ta fram kunskapen till en fungerande lösning. Jag har på något sätt rörat mig utan att känna till den här grundläggande hyresgästen tills nu, men jag planerade bara på allvar. mycket tack!

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *