Se esperaba un operador binario: pregunta de citación para argumentos de script de shell

Tengo una pregunta sobre cómo «estoy agregando argumentos cuando ejecuto un script de shell.

Tengo un script simple que me ayuda a bloquear rangos de 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 ejecuto esto sin argumentos, el resultado es el esperado:

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

Sin embargo, los espacios parecen ser la causa del salida inesperada de «operador binario esperado» :

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

Pero luego lo agrega a pesar de la salida inesperada:

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

Si se trata de un problema de comillas, ¿cómo puedo formar los argumentos (sin usar barras invertidas para escapar de los espacios)? Por supuesto, espero que necesite un cambio al script, esa también es una solución aceptable.

Comentarios

  • Si su objetivo al probar $3 es solo para asegurarse de que haya tres parámetros, luego puede utilizar la variable de shell $# más simple, que contiene el número de parámetros, por ejemplo. if [ $# -ne 3 ].

Responder

Sí, eso es una cita problema: [ ! $3 ] se expande a [ ! south brisbane qld ] (cuatro argumentos entre [ y ]). Y cuando ve cuatro argumentos, con el primero un !, [ espera ver algo como [ ! arg1 op arg2 ] donde op es un operador binario. (esto, nuevamente, es una de las cosas diferentes entre [ .. ] y [[ .. ]]; ver esta Q y también esta Q )

brisbane no es «un operador válido, por lo que se queja y devuelve 2, que es falso, por lo que las declaraciones dentro de if no se ejecutan. Para saber la diferencia entre un error y una prueba fallida normal, necesitaría probar explícitamente el valor de retorno con 2.

Por otro lado, si $3 está vacío, entonces la prueba se convierte en [ ! ], una prueba de un argumento que verifica si el único argumento no está vacío (es, «es la cadena de un carácter !). En ese caso, funciona según lo previsto, aunque quizás no por la razón que esperarías.


Quieres [ ! "$3" ] o [ -z "$3" ] para mantener la cadena como un argumento para [.

Por supuesto, también puede invertir el sentido de la prueba y hacer el trabajo real dentro de if, por lo que un error en la prueba evitaría ejecutar los comandos principales. Pero eso haría que la estructura del código sea un poco más confusa.

Comentarios

  • agradable, entonces la razón por la que está funcionando es que, aunque tiene errores, $ 3 no está ' t vacío, por lo que pasa la prueba! y luego lo cito en el comando iptables por lo que su expansión para incluir espacios ya se maneja, ¿es así?
  • y ellos ' también querré citar los parámetros en la línea de iptables
  • @WEBjuju, ah sí, quise escribir sobre eso, editado por qué funciona. Y sí,tenías las comillas en el comando iptables así que ahí funciona bien.
  • @ilkkachu te tengo, sí, parece una tontería por mi parte. de alguna manera lo supe inconscientemente, pero no pude ' t llevar el conocimiento a una solución funcional. De alguna manera me las arreglé sin conocer a este inquilino básico hasta ahora, pero simplemente subí de nivel. muchas gracias!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *