AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 415990
Accepted
muru
muru
Asked: 2018-01-10 22:44:41 +0800 CST2018-01-10 22:44:41 +0800 CST 2018-01-10 22:44:41 +0800 CST

如果引用的变量为空,如何将其扩展为空?

  • 772

假设我有一个脚本在做:

some-command "$var1" "$var2" ...

而且,如果var1为空,我宁愿将其替换为空字符串而不是空字符串,以便执行的命令为:

some-command "$var2" ...

并不是:

some-command '' "$var2" ...

有没有比测试变量并有条件地包含它更简单的方法?

if [ -n "$1" ]; then
    some-command "$var1" "$var2" ...
    # or some variant using arrays to build the command
    # args+=("$var1")
else
    some-command "$var2" ...
fi

是否有参数替换可以在 bash、zsh 等中扩展为空?我可能仍想在其余参数中使用通配符,因此禁用它并取消引用变量不是一种选择。

bash shell-script
  • 3 3 个回答
  • 9647 Views

3 个回答

  • Voted
  1. Best Answer
    Michael Homer
    2018-01-10T22:51:24+08:002018-01-10T22:51:24+08:00

    符合 Posix 的 shell和Bash 具有 ${parameter:+word}:

    如果参数未设置或为空,则应替换为空;否则,应替换 word 的扩展(如果 word 省略,则为空字符串) 。

    所以你可以这样做:

    ${var1:+"$var1"}
    

    并且已经过var1检查,"$var1"如果它已设置且非空(使用普通的双引号规则),则可以使用它。否则它会扩展为空。请注意,这里仅引用内部部分,而不是全部内容。

    这同样适用于 zsh。你必须重复这个变量,所以它并不理想,但它完全符合你的要求。

    如果您希望将设置但为空的变量扩展为空参数,请${var1+"$var1"}改用。

    • 58
  2. Stéphane Chazelas
    2018-01-12T14:05:32+08:002018-01-12T14:05:32+08:00

    当您zsh省略引号时,默认情况下会这样做:

    some-command $var1 $var2
    

    实际上,您仍然需要在 zsh 中围绕参数扩展引用引号的唯一原因是避免这种行为(空删除),因为当您zsh不引用参数扩展(隐式 split+全球)。

    如果禁用 split 和 glob,则可以对其他类似 POSIX 的 shell 执行相同操作:

    (IFS=; set -o noglob; some-command $var1 $var2)
    

    现在,我认为如果你的变量可以有 0 或 1 值,它应该是一个数组而不是一个标量变量并使用:

    some-command "${var1[@]}" "${var2[@]}"
    

    并使用var1=(value)when var1is 包含一个值,var1=('')何时包含一个空值,以及var1=()何时包含不包含值。

    • 8
  3. Joe
    2018-01-13T20:52:16+08:002018-01-13T20:52:16+08:00

    我在一个 bash 脚本中使用 rsync 遇到了这个问题,该脚本启动了带有或不带有 a-n来切换空运行的命令。事实证明,rsync 和许多 gnu 命令将''作为有效的第一个参数,并且与不存在时的行为不同。

    由于空参数几乎完全不可见,因此调试需要相当长的时间。

    rsync 列表中的某个人向我展示了一种避免此问题的方法,同时也大大简化了我的编码。如果我理解正确,这是@Stéphane Chazelas 最后一个建议的变体。

    在许多单独的变量中构建您的命令参数。这些可以按照适合问题的任何顺序或逻辑进行设置。

    然后,最后,使用变量构造一个数组,将所有内容都放在适当的位置,并将其用作实际命令的参数。

    这样,命令仅在代码中的一个位置发出,而不是针对参数的每个变体重复。

    使用此方法,任何为空的变量都会消失。

    我知道使用 eval 是非常不受欢迎的。我不记得所有的细节,但我似乎需要它来让事情以这种方式工作——这与处理带有嵌入空白的参数有关。

    例子:

    dry_run=''
    if [[ it is a test run ]]
    then
      dry_run='-n'
    fi
    ...
    rsync_options=(
      ${dry_run}
      -avushi
      ${delete}
      ${excludes}
      --stats
      --progress
    )
    ...
    eval rsync "${rsync_options[@]}" ...
    
    • 0

相关问题

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • MySQL Select with function IN () with bash array

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve