Estoy escribiendo este script de bash shell:
#!/bin/bash
declare -i N
read N
for i in {1..$N}
do
echo "Number: $i"
done
(Creo que declare -i N
hace que sea N
un número entero)
Sin embargo, al ejecutar esto, obtengo el siguiente resultado:
>vim new.sh
>chmod +x passgen.sh
>./passgen.sh
15
Number: {1..15}
Aquí quiero tomar el límite del usuario y luego ejecutar el bucle.
Respuesta1
De man bash
:
El orden de las expansiones es: expansión de llaves; expansión de tilde, expansión de parámetros y variables, expansión aritmética y sustitución de comandos (realizada de izquierda a derecha); división de palabras; y expansión del nombre de ruta.
Como puede ver, la expansión de la llave es lo primero, por lo que aparentemente se omite en su problema. En su lugar, usaría un bucle diferente.
Respuesta2
Si bien ya se ha señalado el problema con la expansión de llaves, solo comentaré:
(Creo que declarar -i N hace que N sea un número entero)
Responderé que sí, lo hace, y es un problema ya que lo convierte en una vulnerabilidad de inyección de comandos. Con ese atributo de número entero establecido, siempre que a la variable se le asigna un valor, ese valor se interpreta como una expresión aritmética.
Si el usuario ingresa a[$(reboot)]
en ese read
mensaje, eso provocará un intento de reinicio, por ejemplo.
Ese es un problema general con bash
y zsh
siempre ksh
que se evalúan expresiones aritméticas. Incluso usar la for (( i = 1; i <= N; i++ ))
forma de estilo ksh93 (con o sin declare -i N
) sería un problema ya que el contenido de N
todavía se evalúa en ese contexto aritmético.
for i in {1..$N}
estaría bien (sin declare -i N
) en ksh, zsh o yash -o braceexpand
(se repetiría un galimatías pero no introduciría una vulnerabilidad de inyección de comandos), o podría usar sh
la sintaxis estándar siempre que su sh
implementación no se base en ksh
.
#! /bin/sh -
IFS= read -r N
i=1; while [ "$i" -lt "$N" ]; do
printf '%s\n' "Number: $n"
done
ksh
Todavía [
trata el operando -lt
como expresiones aritméticas, por lo que aún introduciría vulnerabilidades de inyección de comandos. No utilice [[ $i -lt $N ]]
ni (( i < N ))
en bash
// zsh
que ksh
también tengan el problema.
O podría usar awk
/ perl
o cualquier lenguaje de programación adecuado para realizar el ciclo, o podría desinfectar primero la entrada.