rsync从bash脚本运行而不保留所有权

时间:2013-02-25 15:16:58

标签: bash eval rsync

我正在尝试创建一个bash脚本,它将指定为命令行参数的目录同步到远程服务器(也由参数指定)。目前,我正在使用eval,它解决了参数扩展问题,但由于某种原因导致rsync不保留远程文件的所有权(除了邪恶,我知道)。从命令提示符运行带有所有相同标志和参数的rsync命令可以正常工作。

我尝试使用$()作为替代方案,但我陷入了变量扩展的真正混乱,并保护了需要保护远程rsync路径的位(需要引用带空格的路径的反斜杠。)

所以 - 我想2个问题 - 是否有eval阻止rsync保留所有权的原因(bash脚本在源计算机上以root身份运行,ssh以root身份进入远程计算机 - 仅仅是为了现在)?有没有办法让$()在这种情况下工作? (修剪过的)代码如下:

#!/bin/bash

RSYNC_CMD="/usr/bin/rsync"
RSYNC_FLAGS="-az --rsh=\"/usr/bin/ssh -i \${DST_KEY}\""  # Protect ${DST_KEY} until it is assigned later

SRC=${1}  # Normally this is sense checked and processed to be a canonical path

# Logic for setting DST based on command line parameter snipped for clarity - just directly assign for testing

DST='root@some.server.com:'
DST_KEY='/path/to/sshKey.rsa'

TARG=${DST}${SRC//' '/'\ '}  # Escape whitespace for target system

eval ${RSYNC_CMD} ${RSYNC_FLAGS} \"${SRC}\" \"${TARG}\"  # Put quotes round the paths - even though ${TARG} is already escaped

# All synced OK - but ownership not preserved despite -a flag

我尝试将RSYNC_CMD更改为sudo /usr/bin/rsync,并将--rsync-path="sudo /usr/bin/rsync添加到RSYNC_FLAGS,但两者都没有任何区别。我只是看不到我错过的东西......

1 个答案:

答案 0 :(得分:1)

执行此操作的正确方法是使用数组。 -a应该已经暗示-o

RSYNC_CMD="/usr/bin/rsync"

DST='root@some.server.com:'
DST_KEY='/path/to/sshKey.rsa'

RSYNC_FLAGS=(-az --rsh="/usr/bin/ssh -i ${DST_KEY}")

SRC=${1}
TARG="${DST}$SRC"

${RSYNC_CMD} "${RSYNC_FLAGS[@]}" "${SRC}" "${TARG}"

使用RSYNC_RSH代替--rsh,您可以在设置其值之前导出变量。这至少可以让您将导出放在设置其余标志的同一区域。然后,您可以推迟完成其值,直到您拥有正确的身份文件。

RSYNC_CMD="/usr/bin/rsync"
export RSYNC_RSH="/usr/bin/ssh -i %s"  # Use a placeholder for now; set it later
RSYNC_FLAGS=( -a -z )

# Later...

DST='root@some.server.com:'
DST_KEY='/path/to/sshKey.rsa'
RSYNC_RSH=$( printf "$RSYNC_RSH" "$DST_KEY" )


SRC=${1}
TARG="${DST}$SRC"

${RSYNC_CMD} "${RSYNC_FLAGS[@]}" "${SRC}" "${TARG}"