Defina um conjunto de valores para uma variável no shell script

0

Eu quero definir um conjunto de valores para uma única variável. Por exemplo,

singleDigit={0,1,2,3,4,5,6,7,8,9}

Se o usuário der 10, deve sair com um erro.

Como isso pode ser alcançado sem usar um loop, mas uma matriz em vez disso?

    
por Gaurav KS 20.07.2016 / 12:20

2 respostas

3

Se você quiser armazenar vários valores em uma variável, é onde você usa uma matriz como:

allowed_values=(0 1 2 3 4 5 6 7 8 9)

Ou

allowed_values=({0..9})

com bash3+ (a sintaxe emprestada de zsh agora também está disponível em ksh93 ).

E se você quiser verificar se uma determinada string está entre qualquer um desses valores, você pode definir uma função como:

isin() {
  local s
  for s in "${@:2}"; do
    [[ $1 = "$s" ]] && return 0
  done
  return 1
}

if isin "$input" "${allowed_values[@]}"

(em zsh , você pode fazer if ((allowed_values[(eI)$input])) ).

Note que a comparação é léxica (como em 01! = 1). Fazer comparação numérica, você usaria [ "$1" -eq "$s" ] 2> /dev/null (observe que 010 é 10 , não 8 ). Não use [[ $1 -eq $s ]] ou ((s == $1)) , pois eles introduzem vulnerabilidades arbitrárias de injeção de comando.

Se você quiser atribuir um padrão a uma variável para corresponder a alguma entrada, você usaria uma variável escalar e usaria uma das duas sintaxes de padrão 2 (3 com a opção extglob ) suportado por bash :

  • padrão curinga / glob

    pattern='[0-9]'
    

    Usado como:

    case $input in
      ($pattern) echo OK;;
      (*) echo NOK
    esac
    

    ou

    if [[ $input = $pattern ]]; then
      echo OK
    else
      echo NOK
    fi
    
  • Expressão regular estendida:

    regex='^[0-9]$'
    

    usado como:

    if [[ $input =~ $regex ]]; then
      echo OK
    else
      echo NOK
    fi
    

No caso geral, para valores diferentes de um caractere, você usaria:

regex='^(one|two|three)$'

E para padrões , você precisaria da opção extglob :

shopt -s extglob
pattern='@(one|two|three)'

Outra abordagem com bash4+ ou ksh93 ou zsh é usar uma matriz associativa:

Com bash , ksh93 :

typeset -A allowed_values
allowed_values=([one]=1 [two]=1 [three]=1)
if ((allowed_values[$input])); then
  echo OK
else
  echo NOK
fi

Em zsh , o mesmo, mas a sintaxe de atribuição é:

typeset -A allowed_values
allowed_values=(one 1 two 1 three 1)

(observe que, com bash , você não pode ter a string vazia como um valor permitido).

    
por 20.07.2016 / 12:32
0

Se apenas os números de 0 a 9 forem permitidos como entrada, tudo o que você precisa é de uma instrução IF simples.

#!/bin/bash

echo -n Please enter a single digit:
read single_digit
if [ $single_digit -lt 10 ]; then
   echo Thanks for $single_digit
else
   echo Screwball!!! I said SINGLE DIGIT!!
fi
    
por 20.07.2016 / 21:35