【问题标题】:Bash not resolving variableBash 不解析变量
【发布时间】:2022-11-24 02:26:13
【问题描述】:

对 bash 很陌生。我正在尝试编写一个文件来简化对环境列表之一运行 sshuttle 命令的过程。

#!/bin/bash

declare -A environments

environments=(
    [dev]="dev.myhost.com 10.0.1.0/22 --dns"
    [qa]="qa.myhost.com 10.0.2.0/22 --dns"
    [prod]="prod.myhost.com 10.0.3.0/22 --dns"
)

vpn() {
    echo sshuttle --verbose -r ${environments[$1]}
    sshuttle --verbose -r ${environments[$1]}
}

用法将是vpn qa,它应该解析为sshuttle --verbose -r qa.myhost.com 10.0.2.0/22 --dns

不幸的是,当运行 vpn qa 时,我得到一个错误,表明 ${environments[$1]} 在运行时没有被解析:

usage: sshuttle [-l [ip:]port] -r [user@]sshserver[:port] <subnets...>
sshuttle: error: at least one subnet, subnet file, or -N expected

echo 输出我期望看到的内容,并将其复制粘贴到终端中。

我错过了什么?谢谢。

【问题讨论】:

  • 你是如何运行这个功能的?脚本|函数参数问题?
  • @Ivan 我运行source ./sshuttle_vpn.sh 来获取 bash 文件。然后只需在终端上输入vpn qa。回显显示命令应运行的样子。
  • 你的 shell 是 bash 吗?
  • @EricP 还请注意概要,由于手册 sshuttle.readthedocs.io/en/stable/manpage.html#synopsis,我建议将 --dns 选项从 [qa]="qa.myhost.com 10.0.2.0/22 --dns" 移动到命令中 -r ${environments[$1]} 之前的某个位置。
  • @Vab,将 --dns 移动到 -r 之前没有任何区别

标签: bash


【解决方案1】:

zsh 不会像大多数其他 shell 那样对未加引号的变量引用执行分词。这意味着当 ${environments[$1]} 扩展为 qa.myhost.com 10.0.2.0/22 --dns 时,该值将被视为单个长参数(包含空格)而不是三个单独的参数。 echo 的差异不可见,因为它只是在单独的参数之间放置空格,但它对 sshuttle 很重要。 (这是另一个 echo 具有误导性的案例,使用 set -x 来显示正在发生的事情会好得多。)

为了让zsh拆分值,需要在变量引用上加上=修饰符:${=environments[$1]}。当然,这与 bash 不兼容,所以如果你想让它在 bash 和 zsh 中都工作,你需要做这样的事情:

environments=(
    [dev]="dev.myhost.com 10.0.1.0/22 --dns"
    [qa]="qa.myhost.com 10.0.2.0/22 --dns"
    [prod]="prod.myhost.com 10.0.3.0/22 --dns"
)

if [[ -n "$ZSH_VERSION" ]]; then
    # zsh-compatible definition of the function
    vpn() {
        echo sshuttle --verbose -r ${=environments[$1]}
        sshuttle --verbose -r ${=environments[$1]}
    }
else
    # bash-compatible definition of the function
    vpn() {
        echo sshuttle --verbose -r ${environments[$1]}
        sshuttle --verbose -r ${environments[$1]}
    }
fi

请注意,您的脚本中的 #!/bin/bash 被忽略(并且具有误导性)——因为您是 sourceing 它,它在您 sourced 的 shell 中运行,无论是 bash、zsh、dash 还是其他.

【讨论】:

    猜你喜欢
    • 2012-04-28
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    • 2020-10-31
    • 1970-01-01
    • 2022-11-03
    相关资源
    最近更新 更多