Posso comparar o parâmetro de um script a uma matriz de variáveis e processá-lo?

0

Eu quero manipular o valor expandido de uma variável que foi selecionada de uma matriz após a entrada do usuário. Aqui está o que eu quero dizer:

$ ./myscript.sh url2

#!/bin/bash

array=(Sigil wp2epub csskit)

Sigil       =   "https://github.com/Sigil-Ebook/Sigil.git"
csskit      =   "https://github.com/mattharrison/epub-css-starter-kit.git"
wp2epub     =   "https://github.com/mrallen1/wp2md.git"

if [ -z $1 ]; then
  echo "This script needs at least one parameter!"
  exit 1
fi

if [ $1 = Sigil ]; then
  ans=$Sigil # expanded
elif [ $1 = csskit ]; then
  ans=$csskit # expanded
elif [ $1 = wp2epub ]; then
  ans=$wp2epub # expanded
else
  echo "Please inform one of \
        Sigil, csskit or wp2epub!"
fi

git clone $ans

Explicação:

O script verifica a entrada do usuário ($ 1), compara-a com a matriz de variáveis possíveis, se encontrada, recupera o valor expandido dessa variável como resposta e, em seguida, usa o valor expandido (não o nome da variável).

Eu tenho tentado isso há dias, mas minhas limitadas habilidades de script não foram suficientes ...

Obrigado antecipadamente.

Pedido por @terdon: Eu quero que o usuário informe o nome da variável na matriz, que será humana.

As variáveis são, na verdade, os nomes dos pacotes que precisam ser buscados no github (git clone) e depois recompilados e reinstalados.

O uso real seria:

$ ./update.sh Sigil # Sigil is one of the variables

    
por Joe Avg. 09.02.2016 / 15:16

3 respostas

0

No script que você apresenta: $1 contém o nome de uma opção e $array contém o valor das opções. Para obter o resultado na variável $ans expandida conforme solicitado, há algumas opções:

Eval

Um eval: expanda $ 1 para Sigil , por exemplo, e atribua $Sigil para ans:

eval ans\=\"\$\{"$1"\}\"

No entanto, isso pressupõe que $1 seja um rótulo de uma palavra de uma variável. Se a entrada tiver algum outro conteúdo, pode ser possível que seja avaliado por eval. Uma solução eval mais robusta é usar ${array[i]} , pois o conteúdo da matriz é controlado pelo script.

Indirection

Um idiom próximo no bash é ${!1} . Isso é obter o valor de var apontado por $1 , exatamente o que precisamos. Mais uma vez, de forma mais robusta com ${array[i]} (uma vez encontrado o $array[i] correspondente:

a="array[i]"; ans="${!a}"

Matriz associativa

Mas todo o problema de eval e indirecção poderia ser evitado se usarmos um array associativo para as chaves do array e os valores do array.

Então é fácil encontrar o valor correto, se a matriz tiver um valor, é um valor válido. Se a matriz não tiver um valor para uma chave, a chave é inválida.

Um script completo baseado nesse conceito pode ser assim:

#!/bin/bash

[ $# -lt 1 ] && {  echo "This script needs at least one parameter!"; exit 1; }

declare -A a
    a=(
    [Sigil]="https://github.com/Sigil-Ebook/Sigil.git"
    [wp2epub]="https://github.com/mattharrison/epub-css-starter-kit.git"
    [csskit]="https://github.com/mrallen1/wp2md.git"
    )


### Process an error while informing of options.
for    val in "${!a[@]}"
do     d=$d${d:+", "}$last
       last=$val
done
d="Please inform one of $d or $last"
SayError(){ echo "$d" >&2; exit 1; }



### Process a valid command execution.
ExecCmd(){ git clone "$ans"; }



### Process all arguments of script.
for    arg
do     unset ans                          ### unset result variable.
       printf -v ans '%s' "${a[$arg]}"    ### Assign result to "$ans"
       ${ans:+:} SayError                 ### If "$ans" is empty, process error.
       ${ans:+false} || ExecCmd           ### With valid "$ans" execute command.
done

A função SayError pode ser alterada para eliminar o exit 1 , o script ainda processará todos os argumentos, com um aviso para valores inválidos.

    
por 10.02.2016 / 04:29
2

Use uma matriz associativa:

#!/bin/bash

declare -A url
url=( [url1]="http://www.google.com"
      [url2]="http://www.yahoo.com"
      [url3]="http://www.bing.com"
    )

if [[ -z $1 ]] ; then
    echo "This script needs at least one parameter!"
    exit 1
elif [[ -z ${url[$1]} ]] ; then
    echo 'Unknown option'
    exit 1
fi

echo "Let's search ${url[$1]}."
    
por 09.02.2016 / 15:41
0
arr=($url1 $url2 $url3)

for i in ${arr[@]}; do
  if [[ $i == $1 ]] ;then
    ans=$i
    break
  fi
done
    
por 09.02.2016 / 15:38