Concatenação de string Bash usada para construir a lista de parâmetros

12

Dado este pedaço de bash:

PARMS='-rvu'
PARMS+=" --delete --exclude='.git'"
echo $PARMS
rsync ${PARMS} . ${TARGET}

O echo mostra a string PARMS conforme o esperado, nenhum erro é exibido, mas o rsync age silenciosamente como se as opções adicionadas pelo + = não existissem. No entanto, isso funciona como esperado:

PARMS='-rvu'
rsync ${PARMS} --delete --exclude='.git' . ${TARGET}

Acho que estraguei tudo com aspas (sempre tive problemas com elas), mas não sei exatamente o que e por que as opções são ignoradas, mesmo que a string pareça ter sido construída corretamente.

    
por neuviemeporte 28.08.2014 / 09:33

2 respostas

16

Existe uma diferença entre:

PARMS+="... --exclude='.git'"

e

... --exclude='.git'

No primeiro, aspas simples estão dentro das próprias citações, então elas estão literalmente presentes no texto substituído dado a rsync como argumentos. rsync obtém um argumento cujo valor é --exclude='.git' . No segundo, as aspas simples são interpretadas pelo shell no momento em que são escritas, porque elas não estão entre aspas e rsync consegue ver --exclude=.git .

Neste caso, você não precisa das aspas simples - .git é uma palavra de shell perfeitamente válida por si só, sem caracteres especiais, então você pode usá-la literalmente no comando.

Melhor para esse tipo de coisa, no entanto, é um array :

PARMS=(-rvu)
PARMS+=(--delete --exclude='.git')
rsync "${PARMS[@]}"

Isso constrói o seu comando como palavras separadas, com qualquer citação que você queira interpretar no momento em que você escreve a linha do array. "${PARMS[@]}" expande para cada entrada na matriz como um argumento separado , mesmo se o argumento em si tiver caracteres ou espaços especiais, então rsync vê o que você escreveu como quis dizer.

    
por 28.08.2014 / 09:42
2

Além da resposta do @Michael Homer , você pode usar bash função viral :

PARMS='-rvu'
PARMS+=" --delete --exclude='.git'"
echo "$PARMS"
eval "rsync ${PARMS} . "'"${TARGET}"'
    
por 28.08.2014 / 10:10