Estou escrevendo um script de shell para o terminal Linux. Quero poder inserir nomes de variáveis em um prompt. Por exemplo:
teste.sh:
test="Monkey in the middle..."
read -p "Enter input: " input
echo $input
saída:
Enter input: $test
$test
Quero poder inserir "$test" durante o read -p
segmento de prompt do script e fazer com que o script ecoe "Monkey in the middle..." no final, em vez de ecoar "$test" como faz agora.
Como eu faria isso?
ATUALIZAR:
Usando as respostas que me foram fornecidas aqui e emeste tópico(um grande obrigado aos colaboradores e comentaristas!), consegui juntar esta linha que funcionou muito bem para mim:
newvariable="$(eval echo $input)"
Esteja avisado, fui avisado mais de uma vez que o uso de eval pode representar um risco à segurança. Tenha isso em mente se você optar por esta solução.
Responder1
Em vez de
echo "$input"
tentar
eval echo "$input"
Não é nem específico do bash, funciona em/bin/sh!
Observe que isso representa um sério risco de segurança porque eval
apenas executa o que você fornece. Nesse caso, o shell interpreta a string $input
como $test
e depois eval
executa echo $test
. Mas e se o usuário entrar $test; rm -rf *
? eval
seria presenteado com echo $test; rm -rf *
. Tenha muito cuidado se você fizer isso.
Responder2
No bash você pode usar umexpansão indireta de parâmetrossintaxe:
test="Monkey in the middle..."
read -p "Enter input: " input
echo ${!input}
Neste caso, o usuário deve fornecer test
apenas a string sem o cifrão anterior.
Responder3
Contanto que você não se importe que o usuário possa executar comandos arbitrários incluindo uma substituição de comando $(…)
, você pode enviar a string para o eval
built-in. Observe que eval
espera um snippet de shell e, se a entrada incluir aspas, elas poderão causar erros de sintaxe. A maneira (relativamente) fácil de lidar com aspas é usar um documento aqui para realizar as substituições. Você ainda está à mercê de uma variável não terminada ou de uma substituição de comando (por exemplo $(foo
, ).
IFS= read -r -p "Enter input: " input
eval "string=\$(cat <<EOF
_${input}
EOF
)"
string=${string#_}