Não é possível executar o comando dentro da variável bash, incluindo colchetes com nullglob

1

Supondo que eu queira executar o commnand armazenado dentro da variável com o nullglob ativado. Por exemplo:

shopt -s nullglob
a="echo [foo]bar"
${a}

Isso me dá uma saída vazia devido à opção nullglob, claro, mas eu quero a seguinte saída (que eu não sou capaz de obter):

[foo]bar

Eu tentei escapar [] com \ mas isso só me dá:

\[foo\]bar

Qual é a maneira correta de escapar?

EDIT (esclarecimento com algum contexto):

Eu tenho um script como este:

shopt -s nullglob
for file in tmp/*.pdb; do
    base="$(basename ${file} .pdb)"
    a="command --option [${base}]foo"
    ${a}
done
shopt -u nullglob

O que eu queria alcançar é executar o comando para cada arquivo com uma opção que tenha [] caracteres comuns (sem correspondência). O nullglob aqui foi usado apenas para o loop for.

Isto é, se "tmp" contiver "a.pdb", execute:

command --option '[a]foo'

e nada se nenhum arquivo estiver presente.

Entretanto, descobri que mover "shopt -u nullglob" como o primeiro comando no loop for parece resolver o problema. No entanto, estou curioso para saber se de alguma forma posso escapar do [] mesmo com o nullglob.

    
por krab1k 17.09.2015 / 16:11

2 respostas

3

Primeiro, leia Estou tentando colocar um comando em uma variável, mas o casos complexos sempre falham! .

Em seguida, defina uma função:

a () {
    echo "[foo]bar"
}

Para o seu script, não há razão para colocar o comando em uma variável antes; apenas execute o comando.

shopt -s nullglob
for file in tmp/*.pdb; do
    base="$(basename ${file} .pdb)"
    command --option "[${base}]foo"
done
shopt -u nullglob

Se você precisar armazenar algo em variáveis, separe o comando de suas opções e use uma matriz para manter as opções.

shopt -s nullglob
cmd=command
for file in tmp/*.pdb; do
    base="$(basename ${file} .pdb)"
    options=( --option "[${base}]foo" )
    "$cmd" "${options[@]}"
done
shopt -u nullglob
    
por 17.09.2015 / 17:56
1

Eu não entendo porque você está salvando o comando como uma variável. Por que não fazer algo como o que mostro abaixo e evitar o problema?

shopt -s nullglob
for file in tmp/*.pdb; do
    base="$(basename ${file} .pdb)"
    command --option "[${base}]foo"
done
shopt -u nullglob

Como alternativa, se você precisar do comando em uma variável por outros motivos, poderá remover o nullglob e apenas verificar se os arquivos existem antes de executar o comando:

for file in tmp/*.pdb; do
  if [ -e "$file" ]; then
        base="$(basename ${file} .pdb)"
        a="command --option [${base}]foo"
        ${a}
done

Raramente é uma boa ideia salvar comandos como variáveis. Outra abordagem seria salvar as opções como variáveis:

shopt -s nullglob
for file in tmp/*.pdb; do
    base="$(basename ${file} .pdb)"
    a="--option [${base}]foo"
    command "$a"
done
shopt -u nullglob
    
por 17.09.2015 / 16:16