首页 > 解决方案 > 可选地在 bash 脚本中传递参数

问题描述

我想在使用 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 脚本中使用单引号和双引号的好资源,我想阅读它。

标签: bashrsync

解决方案


您要添加两个位置参数:-essh -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,但这会扩展到问题中显示的命令。


推荐阅读