RSYNC="rsync -avzhe 'ssh -i /path/to/deploy_keys/id_rsa' --delete "
# Files
$RSYNC deploy@ip:/var/www/path1 /var/www/path1
$RSYNC deploy@ip:/var/www/path2 /var/www/path2
我想将此RSYNC变量引入更紧凑,但它会引发错误:
Unexpected remote arg: deploy@ip:/var/www/path1
如果我在双引号内只使用rsync,它可以正常工作。为了便于阅读,我要对它们进行单独的命令调用。
答案 0 :(得分:3)
我同意eval
是危险的。除了@Eugeniu Rosca建议的数组方法之外,您还可以使用shell函数:
my_rsync() {
rsync -avzhe 'ssh -i /path/to/deploy_keys/id_rsa' --delete "$@"
}
my_rsync deploy@ip:/var/www/path1 /var/www/path1
my_rsync deploy@ip:/var/www/path2 /var/www/path2
顺便说一句,你应该阅读BashFAQ #50: I'm trying to put a command in a variable, but the complex cases always fail!。
答案 1 :(得分:2)
如果要将命令字符串存储到变量中并在以后进行评估,可以使用eval
或其他更安全的技术:
#!/bin/bash
# Store the command into an array
RSYNC=(rsync -avzhe 'ssh -i /path/to/deploy_keys/id_rsa' --delete)
# Run the command
"${RSYNC[@]}" deploy@ip:/var/www/path1 /var/www/path1
答案 2 :(得分:1)
将字符串分配给变量然后再将其提交给shell后,它会以不同方式进行标记。请考虑以下脚本
VAR="/bin/ls 'Test1 Test2'"
$VAR
会抛出两个错误:
/bin/ls: cannot access 'Test1
/bin/ls: cannot access Test2'
你猜对了,撇号不再影响标记化。相反,当命令行参数传递给/bin/ls
虽然eval
被认为是邪恶的,但它是目前运行脚本的最简单方法。它将所有参数分成一行并再次应用标记化过程。
RSYNC="rsync -avzhe 'ssh -i /path/to/deploy_keys/id_rsa' --delete "
# Files
eval $RSYNC deploy@ip:/var/www/path1 /var/www/path1
eval $RSYNC deploy@ip:/var/www/path2 /var/www/path2