从外部 bash 文件传递变量未按预期运行
Passing variables from external bash file not behaving as expected
我有一个 bash 脚本,它使用 rsync 将一些文件从我的本地桌面备份到我 LAN 上的远程机器。
我在单独的 .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
但是导入的变量没有按预期运行。如果我在任何变量中有任何 space 它会抛出有关变量无效的错误。 bash 似乎对此有奇怪的解释。
即。 rsync_opts="--verbose --archive" 将导致脚本中断和 运行 错误,例如“提供的数字参数无效或未知参数”。其中 rsync_opts="- -冗长”运行非常完美。
为了帮助说明脚本,我已经截取了一些代码片段以显示到目前为止的流程
来自:配置/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=
local l_rsync_backup_file_list=
local l_rsync_exclude_file_list=
local l_rsync_ssh_port=
local l_rsync_ssh_key=
local l_rsync_source=
local l_rsync_dest=
local l_rsync_opts=
#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}"
}
由于您引用 $rsync_opts
,因此整个值作为单个 whitespace-containing 参数传递给 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=
local l_rsync_backup_file_list=
local l_rsync_exclude_file_list=
local l_rsync_ssh_port=
local l_rsync_ssh_key=
local l_rsync_source=
local l_rsync_dest=
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}"
}
我有一个 bash 脚本,它使用 rsync 将一些文件从我的本地桌面备份到我 LAN 上的远程机器。
我在单独的 .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
但是导入的变量没有按预期运行。如果我在任何变量中有任何 space 它会抛出有关变量无效的错误。 bash 似乎对此有奇怪的解释。
即。 rsync_opts="--verbose --archive" 将导致脚本中断和 运行 错误,例如“提供的数字参数无效或未知参数”。其中 rsync_opts="- -冗长”运行非常完美。
为了帮助说明脚本,我已经截取了一些代码片段以显示到目前为止的流程
来自:配置/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=
local l_rsync_backup_file_list=
local l_rsync_exclude_file_list=
local l_rsync_ssh_port=
local l_rsync_ssh_key=
local l_rsync_source=
local l_rsync_dest=
local l_rsync_opts=
#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}"
}
由于您引用 $rsync_opts
,因此整个值作为单个 whitespace-containing 参数传递给 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=
local l_rsync_backup_file_list=
local l_rsync_exclude_file_list=
local l_rsync_ssh_port=
local l_rsync_ssh_key=
local l_rsync_source=
local l_rsync_dest=
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}"
}