1

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

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

所以 - 我猜有两个问题 - 是否有eval阻止rsync保留所有权的原因(bash 脚本在源计算机上以 root 身份运行,并且也以 root 身份运行ssh到远程计算机 - 就目前而言)?在这种情况下有没有办法$()开始工作?(修剪)代码如下:

#!/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_CMDsudo /usr/bin/rsync,并添加--rsync-path="sudo /usr/bin/rsyncRSYNC_FLAGS,但都没有任何区别。我只是看不到我错过了什么......

4

1 回答 1

2

正确的方法是使用数组。-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}"
于 2013-02-25T16:10:22.413 回答