Opérateur binaire attendu – citant la question pour les arguments du script shell

Jai une question sur la façon dont jajoute des arguments lors de lexécution dun script shell.

Jai un script simple qui maide à bloquer les plages dadresses 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" 

Si jexécute ceci sans argument, le résultat est comme prévu:

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

Cependant, les espaces semblent être la cause du sortie inattendue de « opérateur binaire attendu » :

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

Mais ensuite il lajoute malgré la sortie inattendue:

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

Sil sagit dun problème de citation, comment former les arguments (sans utiliser de barres obliques inverses pour échapper aux espaces)? Bien sûr, je pense que jaurai besoin dun changement au script, cest également une solution acceptable.

Commentaires

  • Si votre objectif en testant $3 est juste pour être sûr quil y a trois paramètres, alors vous pouvez utiliser la variable shell $# plus simple, qui contient le nombre de paramètres, par exemple. if [ $# -ne 3 ].

Réponse

Oui, cest « une citation issue: [ ! $3 ] se développe en [ ! south brisbane qld ] (quatre arguments entre [ et ]). Et quand il voit quatre arguments, avec le premier un !, [ sattend à voir quelque chose comme [ ! arg1 op arg2 ]op est un opérateur binaire. (cest encore une des choses différentes entre [ .. ] et [[ .. ]]; voir cette Q et également cette Q )

brisbane nest pas un opérateur valide, donc il se plaint et renvoie 2, ce qui est faux donc les déclarations à lintérieur du if ne sont pas exécutés. Pour faire la différence entre une erreur et un test normal qui échoue, vous devez tester explicitement la valeur de retour par rapport à 2.

En revanche, si $3 est vide, alors le test devient [ ! ], un test à un argument qui vérifie si le seul argument est non vide (cest, cest la chaîne à un caractère !). Dans ce cas, cela fonctionne comme prévu, mais peut-être pas pour la raison que vous attendez.


Vous voulez [ ! "$3" ] ou [ -z "$3" ] pour conserver la chaîne comme argument pour [.

Bien sûr, vous pouvez également inverser le sens du test, et faire le travail réel à lintérieur du if, de sorte quune erreur dans le test éviterait dexécuter les commandes principales. Mais cela rendrait la structure du code un peu plus floue.

Commentaires

  • sympa – donc la raison pour laquelle cela fonctionne alors est que même sil y a des erreurs, $ 3 nest pas ' vide donc il réussit le! test, puis je lai cité dans la commande iptables afin que son expansion pour inclure des espaces soit déjà gérée – est-ce vrai?
  • et ils ' Je voudrais également citer les paramètres de la ligne iptables
  • @WEBjuju, ah oui, je voulais écrire à ce sujet, édité pourquoi cela fonctionne. Et oui,vous aviez les guillemets dans la commande iptables donc là ça marche bien.
  • @ilkkachu gotcha, oui, ça me semble idiot. je le savais dune manière ou dune autre inconsciemment, mais je ne pourrais pas ' apporter ces connaissances à une solution de travail. Je me suis en quelque sorte embrouillé sans connaître ce locataire de base jusquà présent, mais je viens de passer au niveau supérieur. merci beaucoup!

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *