Script Bash que chama um programa com alguns asteriscos nos argumentos

Script Bash que chama um programa com alguns asteriscos nos argumentos

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 echochamada 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 echocom umsolteiroargumento e, além disso, isso me diz que a expansão está acontecendo mais cedo, provavelmente no forciclo.

Mas não posso mudar a forlinha 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 ( -0antes 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"

informação relacionada