我有一个bash脚本,它使用rsync将一些文件从我的本地桌面备份到局域网上的远程机器。
我的主脚本在一个单独的.sh文件中包含一些可自定义的变量,以便于维护,部署和git管理。
所以我有这个目录结构
sync-backup-to-cp.sh
config/settings.sh
以下代码将config / settings.sh包含在主sync-backup-to-cp.sh
中#! /bin/bash
#load variables file
source /Users/enwhat/Dropbox/Flex/Scripts/mac/rysnc-backup-to-cp/config/settings.sh
但是导入的变量的行为不符合预期。如果我在任何变量中有任何空格,则会抛出有关变量无效的错误。似乎bash正在奇怪地解释这一点。
IE中。 rsync_opts =“ - verbose --archive”将导致脚本中断并运行错误,例如“提供无效数字参数或未知参数”。其中rsync_opts =“ - verbose”运行完美。
为了帮助说明脚本,我已经采用了一些代码片段,显示了到目前为止的流程
from:config / settings.sh
RSYNC_OPTS=( --bwlimit=1000 --verbose )
从我的主脚本中,有一个函数调用,传入这些变量。
backup "$RSYNC_BIN" "$BACKUP_FILE_LIST" "$EXCLUDE_FILE_LIST" "$SSH_PORT" "$SSH_KEY" "$SOURCE" "$DESTINATION" "$RSYNC_OPTS[*]"
然后是完整的功能
function backup(){ #uses rsync to backup to server
#takes 8 args 1
#define local vars
local l_rsync_bin=$1
local l_rsync_backup_file_list=$2
local l_rsync_exclude_file_list=$3
local l_rsync_ssh_port=$4
local l_rsync_ssh_key=$5
local l_rsync_source=$6
local l_rsync_dest=$7
local l_rsync_opts=$8
#local l_time
#l_time=$(date)
#caffinate stops system from sleeping
echo ""$l_rsync_bin" "$l_rsync_opts" --verbose --archive --recursive --numeric-ids --human-readable --partial --progress --relative --itemize-changes --stats --rsync-path="sudo rsync" --delete-during --files-from="${l_rsync_backup_file_list}" --exclude-from="${l_rsync_exclude_file_list}" -e "ssh -q -p ${l_rsync_ssh_port} -i ${l_rsync_ssh_key}" "${l_rsync_source}" "${l_rsync_dest}""
caffeinate -s "$l_rsync_bin" "$l_rsync_opts" --verbose --archive --recursive --numeric-ids --human-readable --partial --progress --relative --itemize-changes --stats --rsync-path="sudo rsync" --delete-during --files-from="${l_rsync_backup_file_list}" --exclude-from="${l_rsync_exclude_file_list}" -e "ssh -q -p ${l_rsync_ssh_port} -i ${l_rsync_ssh_key}" "${l_rsync_source}" "${l_rsync_dest}"
}
答案 0 :(得分:2)
由于您引用$rsync_opts
,因此整个值将作为包含空格的单个参数传递给rsync
。为了使每个选项作为单独的参数传递,您需要保持参数展开不加引号:
rsync $rsync_opts
但是,你不能包含实际包含这样的空格的参数;所有空格都被shell视为分隔参数。存储参数的正确方法是使用数组:
rsync_opts=( --verbose --archive )
rsync "${rsync_opts[@]}"
对于您当前的使用案例可能没有必要,但最好养成以正确的方式做事的习惯,以避免以后出现令人讨厌的意外。
例如,
local -a l_rsync_opts
l_rsync_opts=(--bwlimit=1000 --verbose --rsync-path="sudo rsync")
更新:根据您的修改,您需要执行以下操作:
backup ... "${RSYNC_OPTS[@]}" # @, not *
# Note the changes involving l_rsync_opts
function backup(){ #uses rsync to backup to server
#takes 8 args 1
#define local vars
local l_rsync_bin=$1
local l_rsync_backup_file_list=$2
local l_rsync_exclude_file_list=$3
local l_rsync_ssh_port=$4
local l_rsync_ssh_key=$5
local l_rsync_source=$6
local l_rsync_dest=$7
local l_rsync_opts=( "${@:8}" )
#local l_time
#l_time=$(date)
#caffinate stops system from sleeping
echo ""$l_rsync_bin" "${l_rsync_opts[@]}" --verbose --archive --recursive --numeric-ids --human-readable --partial --progress --relative --itemize-changes --stats --rsync-path="sudo rsync" --delete-during --files-from="${l_rsync_backup_file_list}" --exclude-from="${l_rsync_exclude_file_list}" -e "ssh -q -p ${l_rsync_ssh_port} -i ${l_rsync_ssh_key}" "${l_rsync_source}" "${l_rsync_dest}""
caffeinate -s "$l_rsync_bin" "${l_rsync_opts[@]}" --verbose --archive --recursive --numeric-ids --human-readable --partial --progress --relative --itemize-changes --stats --rsync-path="sudo rsync" --delete-during --files-from="${l_rsync_backup_file_list}" --exclude-from="${l_rsync_exclude_file_list}" -e "ssh -q -p ${l_rsync_ssh_port} -i ${l_rsync_ssh_key}" "${l_rsync_source}" "${l_rsync_dest}"
}