Execute um comando armazenado em uma variável $

3

Eu fiz um script onde escrevi:

COMMAND="/usr/bin/exiftool $PATH_NAME"
.... code ....
$COMMAND

A variável $ PATH_NAME é atribuída dinamicamente dentro de um loop while. O comando funciona bem até encontrar arquivos com espaços (por exemplo, PATH_NAME="Adicionar Driver.png"). A saída do console é:

File not found: ./Add
File not found: driver.png

O comando deve ser:

/usr/bin/exiftool ./Add driver.png

Acho que o problema é determinado pelos espaços no $ PATH_NAME. Eu tentei também executar diretamente o comando:

eval "/usr/bin/exiftool $PATH_NAME"

Mas o mesmo erro de saída. Alguma ideia para resolver o problema? obrigado.

    
por Labo29 26.04.2016 / 20:40

3 respostas

4

Em vez de usar strings simples, crie seu comando usando matrizes. As matrizes fornecem uma interface conveniente: Se a for uma matriz, "${a[@]}" (observe as aspas) se expandirá para cada elemento de a , sem divisão adicional de campo ou globbing (portanto, espaços e coisas como curingas, devem permanecer intactas).

Exemplo:

$ a=(printf "|%s|\n" "foo   bar" "*")
$ echo ${a[@]}
printf |%s|\n foo bar bin boot dev etc home lib lib64 lost+found mnt opt proc root run sbin srv sys tmp usr var

Observe como o * foi expandido e como os espaços extras entre foo e bar foram perdidos. Mas com o "${a[@]}" , eles são preservados:

$ echo "${a[@]}"
printf |%s|\n foo   bar *

Isto é ideal para construir comandos. Agora você pode fazer:

$ "${a[@]}"
|foo   bar|
|*|

Veja? Os argumentos foram mantidos perfeitamente.

Então, faça:

COMMAND=(/usr/bin/exiftool "$PATH_NAME")
"${COMMAND[@]}"
    
por muru 30.04.2016 / 08:06
0

O argumento de Glenn Jackman é bem aceito. Mas, para resolver seu caso de uso imediato, que tal os backticks? Assim:

'echo $COMMAND'

Por exemplo, isso funciona:

COMMAND='ls /'
'echo $COMMAND'
    
por matthewn 26.04.2016 / 20:59
0

Para explicações mais detalhadas sobre como o Bash interpreta espaços, recomendo ler isto: Variáveis de Bash e substituição de comando

Solução limpa

A expansão de uma variável pode levar a resultados inesperados e às vezes catastróficos, se a variável contiver caracteres especiais:

user@host:~$ do_something $some_variable

Expandir uma variável entre aspas duplas pode evitar esses problemas:

user@host:~$ do_something "$some_variable"

Explicação

O caso encontrado aqui é descrito no final do post:

  

Os perigos das variáveis não citadas

     

Em um mundo ideal, todos manteriam seus valores de string curtos e sem espaço / nova linha ou qualquer outro caractere especial.

     

[...]

     

Mas quando as pessoas começam a adicionar caracteres especiais a nomes de arquivos, como espaços, as variáveis de expansão, sem o uso de aspas duplas, podem ser perigosas.

     

[...]

     

Assim, o principal objetivo aqui é: citar duas vezes suas referências de variáveis sempre que possível .

    
por darckcrystale 24.04.2017 / 15:02