Operatore binario atteso – domanda di citazione per gli argomenti dello script di shell

Ho una domanda su come aggiungo argomenti durante lesecuzione di uno script di shell.

Ho un semplice script che mi aiuta a bloccare gli intervalli di ip:

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

Se lo eseguo senza argomenti, loutput è come previsto:

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

Tuttavia gli spazi sembrano essere la causa del output imprevisto di “operatore binario previsto” :

~$ ./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 

Ma poi lo aggiunge nonostante loutput imprevisto:

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

Se si tratta di un problema di quotazione, come faccio a formare gli argomenti (senza utilizzare i backslash per sfuggire agli spazi)? Ovviamente, mi aspetto di aver bisogno di una modifica allo script, anche questa è una soluzione accettabile.

Commenti

  • Se il tuo obiettivo nel testare $3 è solo per essere sicuri che ci siano tre parametri, quindi puoi usare la più semplice variabile di shell $#, che contiene il numero di parametri, ad es. if [ $# -ne 3 ].

Risposta

Sì, è una citazione problema: [ ! $3 ] si espande in [ ! south brisbane qld ] (quattro argomenti tra [ e ]). E quando vede quattro argomenti, il primo a !, [ si aspetta di vedere qualcosa come [ ! arg1 op arg2 ] dove op è un operatore binario. (anche questo è una delle cose diverse tra [ .. ] e [[ .. ]]; vedi questa domanda e anche questa Q )

brisbane non è “un operatore valido, quindi si lamenta e restituisce 2, che è falso quindi le istruzioni allinterno del if non vengono eseguiti. Per capire la differenza tra un errore e un normale test non riuscito, devi testare esplicitamente il valore restituito rispetto a 2.

Daltra parte, se $3 è vuoto, quindi il test diventa [ ! ], un test di un argomento che controlla se lunico argomento è non vuoto (lo è, è la stringa di un carattere !). In tal caso, funziona come previsto, anche se forse non per il motivo che “ti aspetteresti.


Vuoi [ ! "$3" ] o [ -z "$3" ] per mantenere la stringa come un argomento per [.

Ovviamente potresti anche invertire il senso del test e fare il lavoro effettivo allinterno del if, in modo che un errore nel test eviterebbe di eseguire i comandi principali. Ma ciò renderebbe la struttura del codice un po più poco chiara.

Commenti

  • bello – quindi il motivo per cui funziona è che, anche se si sbaglia, $ 3 non è ' vuoto quindi supera il! test e poi lho citato nel comando iptables quindi la sua espansione per includere spazi è già gestita – è giusto?
  • e loro ' voglio citare anche i parametri nella riga iptables
  • @WEBjuju, ah sì, volevo scrivere su questo, ho modificato il motivo per cui funziona. E sì,avevi le virgolette nel comando iptables quindi funziona bene.
  • @ilkkachu gotcha, sì, sembra sciocco da parte mia. in qualche modo lo sapevo inconsciamente ma non potevo ' portare la conoscenza a una soluzione funzionante. Fino ad ora mi sono arrangiato senza conoscere questo inquilino di base, ma sono semplicemente salito di livello. grazie mille!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *