可选择在 bash 脚本中传递一个参数
Optionally pass an argument in a bash script
我想在使用 rsync 时使用自定义身份文件,但前提是该文件存在,否则我不想为 rsync 使用自定义 ssh 命令。我在引用时遇到问题。查看示例。
如果身份文件存在则需要命令
rsync -e "ssh -i '/tmp/id_rsa'" /tmp/dir/ u@h:/tmp/dir
身份文件不存在时需要的命令
rsync /tmp/dir/ u@h:/tmp/dir
我想创建一个包含 -e "ssh -i '/tmp/id_rsa'"
的变量并按如下方式使用它
rsync ${identityArg} /tmp/dir/ u@h:/tmp/dir
此变量可以为空或包含所需的 ssh 命令。
我填充变量的一个例子(我试过很多方法)
IDENTITY_FILE="/tmp/id_rsa"
if [ -f "${IDENTITY_FILE}" ]; then
identityArg="-e 'ssh -i \"${IDENTITY_FILE}\"'"
fi
问题是命令中的引号总是错误的,我最终得到了与这些类似的命令(set -x
在脚本中设置,这是输出)
rsync -e '\ssh' -i '"/tmp/id_rsa"'\''' /tmp/dir/ u@h:/tmp/dir
关于 bash 中的引用,我有一些不明白的地方。如果您有任何关于在 bash 脚本中使用单引号和双引号的好资源,我想阅读它。
您想添加两个位置参数:-e
和 ssh -i '/tmp/id_rsa'
,其中 /tmp/id_rsa
是扩展变量。你应该为此使用一个数组:
args=(/tmp/dir/ u@h:/tmp/dir)
idfile=/tmp/id_rsa
# Let [[ ... ]] do the quoting
if [[ -f $idfile ]]; then
# Prepend two parameters to args array
args=(-e "ssh -i '$idfile'" "${args[@]}")
fi
rsync "${args[@]}"
我不相信内部单引号对于 ssh -i
是必要的,但这扩展到问题中显示的命令。
这样试试
id=/tmp/id_rsa
[[ -e $id ]] && o1='-e' o2="ssh -i '$id'"
echo $o1 "$o2" /tmp/dir/ u@h:/tmp/dir
尝试正确转义引号很棘手。最好尝试利用现有结构。很少有选择,视情况而定
如果身份文件的名称仅包含简单字符(无空格、通配符等),请考虑不要将其括在引号中。在这种情况下,您可以
IDENTITY_FILE="/tmp/id_rsa"
if [ -f "${IDENTITY_FILE}" ]; then
identityArg="-e 'ssh -i ${IDENTITY_FILE}'"
fi
...
rsync $identityArg ...
另一种选择是始终传递命令(ssh 或 'ssh -I ...')。这将自动处理身份文件中的特殊字符。
IDENTITY_FILE="/tmp/id_rsa"
if [ -f "${IDENTITY_FILE}" ]; then
identityArg="-i '${IDENTITY_FILE}'"
fi
rsync -e "ssh $identityArg" ...
第三种选择是使用数组创建 rsync
的参数,并让 shell 根据需要转义字符。这将允许身份文件中的任何字符。
IDENTITY_FILE="/tmp/id_rsa"
if [ -f "${IDENTITY_FILE}" ]; then
identityArg=(-e "ssh -i '${IDENTITY_FILE}'")
fi
rsync "${identityArg[@]}" ...
我想在使用 rsync 时使用自定义身份文件,但前提是该文件存在,否则我不想为 rsync 使用自定义 ssh 命令。我在引用时遇到问题。查看示例。
如果身份文件存在则需要命令
rsync -e "ssh -i '/tmp/id_rsa'" /tmp/dir/ u@h:/tmp/dir
身份文件不存在时需要的命令
rsync /tmp/dir/ u@h:/tmp/dir
我想创建一个包含 -e "ssh -i '/tmp/id_rsa'"
的变量并按如下方式使用它
rsync ${identityArg} /tmp/dir/ u@h:/tmp/dir
此变量可以为空或包含所需的 ssh 命令。
我填充变量的一个例子(我试过很多方法)
IDENTITY_FILE="/tmp/id_rsa"
if [ -f "${IDENTITY_FILE}" ]; then
identityArg="-e 'ssh -i \"${IDENTITY_FILE}\"'"
fi
问题是命令中的引号总是错误的,我最终得到了与这些类似的命令(set -x
在脚本中设置,这是输出)
rsync -e '\ssh' -i '"/tmp/id_rsa"'\''' /tmp/dir/ u@h:/tmp/dir
关于 bash 中的引用,我有一些不明白的地方。如果您有任何关于在 bash 脚本中使用单引号和双引号的好资源,我想阅读它。
您想添加两个位置参数:-e
和 ssh -i '/tmp/id_rsa'
,其中 /tmp/id_rsa
是扩展变量。你应该为此使用一个数组:
args=(/tmp/dir/ u@h:/tmp/dir)
idfile=/tmp/id_rsa
# Let [[ ... ]] do the quoting
if [[ -f $idfile ]]; then
# Prepend two parameters to args array
args=(-e "ssh -i '$idfile'" "${args[@]}")
fi
rsync "${args[@]}"
我不相信内部单引号对于 ssh -i
是必要的,但这扩展到问题中显示的命令。
这样试试
id=/tmp/id_rsa
[[ -e $id ]] && o1='-e' o2="ssh -i '$id'"
echo $o1 "$o2" /tmp/dir/ u@h:/tmp/dir
尝试正确转义引号很棘手。最好尝试利用现有结构。很少有选择,视情况而定
如果身份文件的名称仅包含简单字符(无空格、通配符等),请考虑不要将其括在引号中。在这种情况下,您可以
IDENTITY_FILE="/tmp/id_rsa"
if [ -f "${IDENTITY_FILE}" ]; then
identityArg="-e 'ssh -i ${IDENTITY_FILE}'"
fi
...
rsync $identityArg ...
另一种选择是始终传递命令(ssh 或 'ssh -I ...')。这将自动处理身份文件中的特殊字符。
IDENTITY_FILE="/tmp/id_rsa"
if [ -f "${IDENTITY_FILE}" ]; then
identityArg="-i '${IDENTITY_FILE}'"
fi
rsync -e "ssh $identityArg" ...
第三种选择是使用数组创建 rsync
的参数,并让 shell 根据需要转义字符。这将允许身份文件中的任何字符。
IDENTITY_FILE="/tmp/id_rsa"
if [ -f "${IDENTITY_FILE}" ]; then
identityArg=(-e "ssh -i '${IDENTITY_FILE}'")
fi
rsync "${identityArg[@]}" ...