Estou escrevendo este script bash shell:
#!/bin/bash
declare -i N
read N
for i in {1..$N}
do
echo "Number: $i"
done
(Acredito que declare -i N
seja N
um número inteiro)
No entanto, ao executar isso, recebo a seguinte saída:
>vim new.sh
>chmod +x passgen.sh
>./passgen.sh
15
Number: {1..15}
Aqui eu quero pegar o limite do usuário e depois executar o loop.
Responder1
De man bash
:
A ordem das expansões é: expansão de chaves; expansão de til, expansão de parâmetros e variáveis, expansão aritmética e substituição de comandos (feita da esquerda para a direita); divisão de palavras; e expansão do nome do caminho.
Como você pode ver, a expansão das chaves é a primeira, então aparentemente ela foi ignorada no seu problema. Eu usaria um loop diferente.
Responder2
Embora o problema com a expansão de chaves já tenha sido apontado, vou apenas comentar:
(Acredito que declare -i N torna N um número inteiro)
Eu responderei que sim, e é um problema, pois o torna uma vulnerabilidade de injeção de comando. Com esse atributo inteiro definido, sempre que um valor é atribuído à variável, esse valor é interpretado como uma expressão aritmética.
Se o usuário entrar a[$(reboot)]
nesse read
prompt, isso causará uma tentativa de reinicialização, por exemplo.
Esse é um problema geral bash
e zsh
sempre ksh
que expressões aritméticas são avaliadas. Mesmo usar o for (( i = 1; i <= N; i++ ))
formulário no estilo ksh93 (com ou sem declare -i N
) seria um problema, pois o conteúdo de N
ainda é avaliado nesse contexto aritmético.
for i in {1..$N}
ficaria bem (sem declare -i N
) em ksh, zsh ou yash -o braceexpand
(faria um loop sem sentido, mas não introduziria uma vulnerabilidade de injeção de comando), ou você poderia usar sh
a sintaxe padrão, desde que sua sh
implementação não seja baseada em ksh
.
#! /bin/sh -
IFS= read -r N
i=1; while [ "$i" -lt "$N" ]; do
printf '%s\n' "Number: $n"
done
ksh
ainda [
trata operandos -lt
como expressões aritméticas, portanto ainda introduziria vulnerabilidades de injeção de comando. Não use [[ $i -lt $N ]]
ou (( i < N ))
em bash
// zsh
que ksh
também tem o problema.
Ou você pode usar awk
/ perl
ou qualquer linguagem de programação adequada para fazer o loop, ou primeiro limpar a entrada.