Expansão de Bash de $ {@} como comando

3

Eu tenho um script pai

while read cmd 
do
  nohup ./script ${cmd[@]} &>> log &
done < ~/list 

que executa este script filho

while true
do 
  eval "${CMD[@]}"
  #${CMD[@]}
  #./panic
done

com esta lista de comandos

node ~/www/splash/app.js
node ~/www/splash-two/app.js

Quando o script filho chama eval ${CMD[@]} , ele é executado da maneira que eu esperava executando esse comando sem queixas, mas quando tento remover o eval e executar o comando usando ${CMD[@]} ele gera o erro:

Error: Cannot find module '/home/rumplefraggle/SYS/RABBOT/~/www/splash/app.js'

Agora eu pensei que possivelmente isso tinha algo a ver com o comando node, então eu tentei executar ls ~
como o comando e lança o erro que ~ não pode ser encontrado.

Ecoando ${@} e não executando, expande como eu esperava.

Também inserir manualmente o comando no script filho também funciona como esperado

Eu não entendo porque eval funciona e simplesmente executando o comando usando ${@} não. O que está causando ${@} para não expandir o ~ ?

Por que o nó está anexando o nome do diretório ao comando quando ${@} é usado?

    
por Prospero 09.07.2013 / 19:57

2 respostas

3

Isto é devido à expansão do til. O eval expande o til, que é substituído pelo caminho completo para o diretório inicial. Sem ele, o comando obtém um til literal passado e tenta usar um caminho relativo (que não existe).

$ echo ~
/home/chris
$ echo "~" 
~
$ eval 'echo ~' 
/home/chris 
    
por 09.07.2013 / 20:11
0

Você precisa de citações: "${cmd[@]}"

Sem as aspas, todos os elementos da matriz são preenchidos em uma única string. Com aspas, cada elemento será manipulado adequadamente individualmente.

De o manual :

If the subscript is ‘@’ or ‘*’, the word expands to all members of the array name. These subscripts differ only when the word appears within double quotes. If the word is double-quoted, [...] ${name[@]} expands each element of name to a separate word.

    
por 09.07.2013 / 21:46