Como mostro um número entre 1 e 100 e mostro se o número está fora do limite? [fechadas]

0
#!/bin/bash/  

echo "Choose a number between 1 and 100"  
read num  
num=num  
echo  
if [ $num -lt 100 -o -gt 1 ]; then  
       echo "You chose $num"  
elif [ $num -gt 100 -o -lt 1 ]; then  
       echo "you chose a number outside of the boundary"  
fi
    
por T13 10.06.2018 / 03:28

3 respostas

4

Com a sintaxe POSIX sh:

#! /bin/sh - 

printf 'Choose a decimal integer number between 1 and 100: '
IFS= read -r num

die() {
  printf >&2 '%s\n' "$@"
  exit 1
}
case $num in
  ("" | - | *[!0123456789-]* | ?*-*)
    die "$num is not a valid decimal integer number";;
  (*[123456789]??*)
    die "You chose a number outside the boundaries"
esac

if [ "$num" -lt 1 ] || [ "$num" -gt 100 ]; then  
  die "You chose a number outside the boundaries"
fi

echo "You chose $num"
  • número é ambíguo. 0xAA , MMXVIII , ¾ , 010 , 1.4e+4 , infinity são todos números por alguma definição de número . Muitos shells do tipo POSIX, incluindo bash , suportam apenas inteiros decimais em seus [ builtin (e decimal, octal, hexadecimal em suas expressões aritméticas). É melhor qualificar exatamente o tipo de número desejado. Aqui inteiro decimal, por exemplo.
  • O uso de cadeias arbitrárias em uma expressão aritmética e em alguns shells no comando [ é uma vulnerabilidade de injeção de comando . Então você gostaria de verificar se o número de entrada se parece com um número primeiro.
  • IFS= read -r line é a sintaxe para ler uma linha de entrada (embora aqui a manipulação $IFS -stripping e continuação de linha de read num provavelmente seja OK).
  • expansões de parâmetros precisam ser citadas em shells semelhantes a Bourne
  • Você teve uma falha na sua lógica. Você usou ou em vez de e . Todos os números decimais são maiores que 1 ou menos que 100.
  • Os operadores -o e -a [ estão obsoletos conforme fazem para expressões de teste que não podem ser interpretadas de forma confiável. Enquanto aqui, não seria um problema, uma vez que tenhamos certeza de que os argumentos são números inteiros decimais, eles devem ser evitados. É melhor usar várias invocações de [ separadas por && ou || de operadores de shell.
  • É melhor enviar mensagens de erro no stderr ( >&2 ) e sair com um status de saída diferente de zero em caso de falha.
  • A maioria dos shells usa os tipos de dados inteiros do compilador para seus operadores inteiros. Para a maioria dos shells na maioria dos sistemas, 2 64 +50 por exemplo (18446744073709551666) seria muito grande para essa representação interna. Dependendo da implementação [ do shell, ele não seria reconhecido como um número (bash, dash, yash), truncado para 19 dígitos com um aviso (zsh), aproximado como um número flutuante (ksh93) ou considerado como o mesmo que 50) (mksh). Portanto, você pode descobrir que [ 18446744073709551666 -gt 0 ] retorna falso ou que [ 18446744073709551666 -le 100 ] retorna verdadeiro. Daí a verificação *[123456789]??* para mais de 3 dígitos.
  • observe que, se o usuário inserir um caractere NUL como parte de sua entrada, o comportamento variará entre os shells.

Com bash especificamente, você pode deixar um pouco menos complicado com:

#! /bin/bash - 

IFS= read -rp 'Choose a decimal integer number between 1 and 100: ' num

die() {
  printf >&2 '%s\n' "$@"
  exit 1
}
[[ $num =~ ^-?[0123456789]+$ ]] ||
  die "$num is not a valid decimal integer number"

[[ $num = *[123456789]??* ]] ||
  ((num < 1 || num > 100)) &&
  die "You chose a number outside the boundaries"

echo "You chose $num"
    
por 10.06.2018 / 11:18
3

Usando o teste de shell:

#!/bin/bash
read -rp "Choose a number between 1 and 100: " num
echo  
if [ "$num" -le 100 -a "$num" -ge 1 ]; then  
       echo "You chose $num"  
else 
       echo "you chose a number outside of the boundary"  
fi

Usando o teste estendido de bash:

#!/bin/bash
read -rp "Choose a number between 1 and 100: " num
echo  
if [[ "$num" -le 100 && "$num" -ge 1 ]]; then  
       echo "You chose $num"  
else
       echo "you chose a number outside of the boundary"  
fi

Usando aritmética de shell:

#!/bin/bash
read -rp "Choose a number between 1 and 100: " num
echo  
if ((num<=100 && num>=1)); then  
       echo "You chose $num"  
else  
       echo "you chose a number outside of the boundary"  
fi

Observação: você está usando -o para ou , mas parece que deseja -a para e . Com ou apenas uma condição precisa passar, então o número pode ser -1 ou 101.

Além disso, o lado direito do -o é como um teste totalmente novo, portanto, é necessário reintroduzir a variável nesse lado. Além disso, estou usando apenas else em vez da instrução elif , porque se o número não passar no primeiro teste, não será necessário realizar outro teste nele.

    
por 10.06.2018 / 03:36
0

A segunda linha abaixo é um erro fatal, (provavelmente deveria ser num="$num" ), mas a linha seria desnecessária se estivesse correta.

read num
num=num

Se o usuário inserir o número "1" , a segunda linha mudará para a cadeia não numérica "num" . Que iria quebrar todo o número de verificação vinculada depois.

Para corrigir isso, basta excluir a segunda linha.

    
por 10.06.2018 / 08:32

Tags