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
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!
$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 ]
.