Parâmetro ignorado quando citado

2

Eu tenho um diretório com 3 arquivos: file1 , file2 e o seguinte script bash:

#!/bin/bash
set -e

Command="ls -1 -I file1"
echo "Command: $Command"

Files='$Command'
echo "Files:"
echo $Files

O resultado é o esperado. Ou seja file1 é ignorado e não é exibido na listagem:

$ ./test.sh
Command: ls -1 -I file1
Files:
file2
test.sh

Agora, e se eu quisesse suportar ignorar arquivos com um espaço no nome? Eu deveria colocar o nome do arquivo entre aspas, certo? Bem ...

#!/bin/bash
set -e

Command="ls -1 -I 'file1'"
echo "Command: $Command"

Files='$Command'
echo "Files:"
echo $Files

rendimentos:

$ ./test.sh
Command: ls -1 -I 'file1'
Files:
file1
file2
test.sh

No entanto, avaliar o mesmo comando diretamente no bash produz corretamente:

$ ls -1 -I 'file1'
file2
test.sh

O que está acontecendo aqui? Adicionar citações parece jogar fora algo errado, mas por quê?

Não ajuda substituir o comando com nada do tipo:

Command="ls -1 -I \"file1\""
Command="ls -1 --ignore='file1'"

Nem ajuda a mudar a avaliação do comando:

Files=$($Command)
Files=$('echo $Command')

Parece que o comportamento correto só pode ser recuperado com a introdução de um eval

Files=$(eval $Command)
Files='eval $Command'

Estou muito curioso para entender por que ls é avaliado e executado, mas de alguma forma os argumentos citados para ele são ignorados, a menos que eval seja adicionado.

    
por Krokeledocus 09.12.2015 / 17:24

1 resposta

2

Como a remoção de cotações não será aplicada para citar caracteres se eles próprios tiverem sido citado.

Em:

Command="ls -1 -I 'file1'"

A cotação única ' foi cotada por aspas duplas", por isso é considerada uma parte da sequência. Você pode usar printf com %q (em bash , ksh e zsh ) para verificar:

$ printf '%q\n' "$Command"
ls -1 -I 'file1'

Se você executar diretamente no terminal, a aspa simples não foi citada e foi removida pelo shell.

    
por 09.12.2015 / 17:42