Passei a última hora tentando escrever um script bash bem simples e nunca me senti tão idiota.
Portanto, tenho uma lista de strings (que são especificações do seletor de pacotes para um gerenciador de pacotes, se isso for importante) que podem conter asteriscos. Preciso construir uma linha de comando preservando esses asteriscos e depois chamar um programa. Aqui está minha tentativa ingênua:
xs="foo/bar */*"
xs_cmd=""
for x in $xs; do
xs_cmd="$xs_cmd -0 $x "
done
echo $xs_cmd
Preciso que a echo
chamada seja equivalente a
echo -0 foo/bar -0 '*/*'
quais saídas -0 foo/bar -0 */*
.
PS Na realidade, a primeira linha é um pouco mais complexa: xs="$some foo/bar */* $(get_others)"
.
Se você executar este script em um diretório contendo a/b
, você obterá -0 foo/bar -0 a/b
.
Quando eu mudo a última linha para
echo "$xs_cmd" # note the quotes
eu entendo -0 foo/bar -0 a/b
e, antes de mais nada, não é isso que eu quero, já que agora estou invocando echo
com umsolteiroargumento e, além disso, isso me diz que a expansão está acontecendo mais cedo, provavelmente no for
ciclo.
Mas não posso mudar a for
linha porque
for x in "$xs"; do # note the quotes
fará com que o loop itere apenas uma vez: -0 foo/bar */*
(há um único -0
), portanto, adicionar essas aspas não é uma opção com certeza.
Agora, se eu voltar ao script original e substituir a primeira linha por
xs="foo/bar '*/*'" # note additional single quotes
Eu entendo -0 foo/bar -0 '*/*'
(aspas simples não deveriam estar lá).
Parece que tentei todas as combinações de aspas e escapes de barra invertida de asteriscos e literalmente não tenho ideia do que fazer agora.
Responder1
Usei seu script original, mas com aspas simples na primeira linha (apenas) e funcionou como acho que você deseja ( -0
antes de cada caminho de arquivo): -
xs='foo/bar */*'
xs_cmd=""
for x in $xs; do
xs_cmd="$xs_cmd -0 $x "
done
echo $xs_cmd
Você provavelmente encontrará problemas ao usá-lo se houver espaços em branco incorporados em qualquer um dos caminhos de arquivo. Nesse caso, altere o comando no loop para: -
xs_cmd="$xs_cmd -0 \"$x\" "
Responder2
Dependendo do que você está tentando alcançar, você precisa citar estes */*
:
xs="foo/bar '*/*'" #!
xs_cmd=""
for x in $xs ; do
xs_cmd="$xs_cmd -0 $x "
done
echo $xs_cmd
eval echo $xs_cmd
eval "echo $xs_cmd"
ou use matrizes, ou ambos:
xs=("foo/bar" "*/*") #!
xs_cmd=""
for x in "${xs[@]}"; do
xs_cmd="$xs_cmd -0 '$x' " #!
done
echo "$xs_cmd"
eval "echo $xs_cmd"