Como faço para escapar corretamente de um padrão de exclusão de rsync usado em um script bash?

1

Script:

#!/bin/bash

site=$1
remote_host=$2
new_site=${3:-$1}

cmd="rsync -rlpuvz -e ssh /www/$site/ $remote_host:/www/$new_site --force --delete --exclude=\"site/web_sitemap_*.xml.gz\""
echo $cmd
$cmd

Saída de script:

[xxx@xxx ~]$ rsync -rlpuvz -e ssh /www/xxx/ xxx:/www/xxx --force --delete --exclude="site/web_sitemap_*.xml.gz"

sending incremental file list
deleting site/web_sitemap_ff3abe06_000.xml.gz

Parece estar tratando as citações \" como caracteres literais " filename / pattern. Eu recebo a mesma coisa com aspas simples (sem escape) ' como em "--exclude='site/web_sitemap_*.xml.gz'" . No entanto, se tentamos a mesma coisa sem qualquer tipo de citações embutidas, funciona! Versão sem aspas:

[xxx@xxx ~]$ touch /www/xxx/site/web_sitemap_ff3abe06_000.xml.gz

[xxx@xxx ~]$ rsync -rlpuvz -e ssh /www/xxx/ xxx:/www/xxx --force --delete --exclude=site/web_sitemap_*.xml.gz

sending incremental file list

sent 41624 bytes  received 290 bytes  7620.73 bytes/sec
total size is 18233892  speedup is 435.03

Não usar citações parece ser a resposta, mas como proteger contra expansão de shell ou interpretação de caracteres especiais em casos em que o padrão de exclusão rsync contém símbolos que normalmente seriam expandidos ou interpretados por bash (como : ou ; ou \ ou [ )?

    
por SpliFF 23.07.2014 / 07:51

1 resposta

1

Você deve ler o BashFAQ / 050, também conhecido como "Estou tentando colocar um comando em uma variável, mas os casos complexos sempre falham! .

Um TL; DR:

This fails because [...] the [...] quotes inside the variable are literal; not syntactical.

A divisão de palavras também é um problema ao tentar armazenar um comando em uma variável. Embora não seja com o seu exemplo imediato, isso é algo que se deve ter em mente.

Depois de ler #050 , você poderá reavaliar se realmente precisar fazer isso. Se você ainda acha que faz e decide desconsiderar o conselho, você vai querer armazenar seu comando em uma matriz:

cmd=( rsync -rlpuvz -e ssh "/www/${site}/" "${remote_host}:/www/${new_site}" --force --delete --exclude="site/web_sitemap_*.xml.gz" )
"${cmd[@]}"
    
por 23.07.2014 / 08:06

Tags