sh - Shell脚本如何在变量内传递带有空格的参数
问题描述
我正在制作一个脚本来通过 ssh 将目录与 rsync 同步。当我想定义一个自定义端口时,我遇到了麻烦。假设一个正常的工作脚本有一个语法:
#! /bin/sh
rval=2222
port="ssh -p $rval"
rsync --progress -av -e "$port" sflash@192.168.10.107:/home/sflash/Documents/tmp/tcopy/ /home/sflash/Documents/tmp/tcopy
公开自定义端口时的语法是-e "ssh -p 2222"
. 但是,如果我想在这种情况下使用变量,例如:
#! /bin/sh
rval=2222
port="-e \"ssh -p $rval\""
rsync --progress -av $port sflash@192.168.10.107:/home/sflash/Documents/tmp/tcopy/ /home/sflash/Documents/tmp/tcopy
由于与 IFS 的某种交互,这可能不会起作用。如果我引入一个 if 语句来检查是否port
已定义,我可以完全避免这种情况,但我很好奇失败的确切原因以及是否存在强制实施此方法的解决方案。
编辑:对不起,我仅限于 posix shell
解决方案
您实际上没有提供足够的细节来确定,但我怀疑您遇到了一个常见的误解。
当你这样做时:
rval=2222
rsync --progress -av -e "ssh -p $rval" src dst
rsync
使用 6 个参数调用:--progress
、-av
、-e
、ssh -p 2222
、src
和dst
.
另一方面,当你这样做时:
port="-e \"ssh -p $rval\""
rsync --progress -av $port src dst
rsync
使用 8 个参数调用:--progress
, -av
, -e
, "ssh
, -p
, 2222"
, src
, 和dst
.
您不希望将双引号传递给rsync
,也不希望ssh -p 2222
将 拆分为 3 个参数。做你想做的事情的一种(可怕的)方法是使用eval
. 但似乎你真正想要的是:
rval=2222
port="ssh -p $rval"
rsync --progress -av ${port:+-e "$port"} src dst
现在,如果定义了端口而不是空字符串,rsync
将使用附加参数-e
和ssh -p 2222
(根据需要)调用,如果端口未定义或为空,则既不使用-e
也不使用$port
参数。
请注意,在这种情况下,您不能在 . 周围使用双引号${port:+-e "$port"}
。如果这样做,则空字符串将作为参数传递 when$port
是空字符串。当$port
不是空字符串时,它会传递一个参数-e ssh -p 2222
而不是分成 2 个参数-e
和ssh -p 2222
.
推荐阅读
- python - 从 docker 容器中获取 sftp 服务器的主机 url
- angularjs - 在授权解决之前加载 AngularJS 模板 URL
- less - LESS:以类似于“嵌套规则”的方式创建变量
- laravel - 在 Laravel 5.8 中调用未定义的方法 Maatwebsite\Excel\Excel::create()
- python-3.x - 当我在 chrome web 驱动程序中加载带有活动登录名和书签等的用户数据 chrome 配置文件时,web 驱动程序 add_experimental_options () 不起作用
- lua - Roblox Studio Lua:使用本地脚本克隆
- sql - 如何从 Pentaho-Kettle 中基于动态选择的 sql 查询中获取结果集?
- ansible - Ansible jinja2 未使用 with_items 连接到列表
- javascript - 具有多个订阅的淘汰单个 observable
- javascript - 如何解决invariant Violation的错误:Native module cannot be null()