Rsync命令变量,bash脚本

时间:2015-07-08 10:51:24

标签: bash rsync

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,它可以正常工作。为了便于阅读,我要对它们进行单独的命令调用。

3 个答案:

答案 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

Why eval should be avoided

答案 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