
Aqui está meu pequeno trecho de script bash.
i=5
command='echo $i'
$command
Quero que este script seja impresso 5
, ou seja, quero que ele execute echo e imprima 5. Mas, em vez disso, ele continua imprimindo $i
. Então, como faço para resolver isso?
Responder1
Isso seria:
eval "$command"
Se você deseja que o conteúdo $command
seja avaliado como código shell.
Se você não pode garantir que isso $command
não começará -
(o que faria com eval
que alguns shells gostassem bash
de tratá-lo como uma opção), você pode querer executar:
eval " $command"
em vez de. Esse espaço inicial extra não afetará a maneira como o comando é analisado e impedirá $command
que seja tratado como uma opção eval
se começar com -
. eval -- "$command"
também funcionaria em alguns shells (incluindo bash
), mas não é POSIX (IIRC) e não funcionaria no dash
shell Bourne, por exemplo.
Observe que você $command
provavelmente deveria ser:
command='echo "$i"'
A menos que você pretendesse $i
estar sujeito a split+glob
Uma maneira potencialmente melhor de armazenar código em “variáveis” seria usar funções:
mycommand() { echo "$i"; }
(usando mycommand
em vez de command
, como command
já é um comando existente).
Se $command
for break
// continue
, return
o comportamento irá variar dependendo do shell.
Se você quisesse $command
armazenar umcomando simples, que é uma lista de palavras, a primeira das quais é procurada como o comando a ser executado com a lista de palavras como argumentos, você usaria uma variável de array:
command=('echo' '$i' "$i")
"${command[@]}"
Isso seria executado echo
, com echo
e $i
o conteúdo de $i
como argumentos.
command='echo $i ;x /* '$i
$command
(com o valor padrão de $IFS
) é o que faria menos sentido. Lá, $command
conteria uma string. O primeiro $i
deixado como está, o segundo expandido (fora das aspas simples) e então essa string estaria sujeita a split + glob (como $command
não está entre aspas duplas), cujo resultado resultaria em uma série de palavras, tomadas como umcomando simplesde novo.