Bash 环境变量的 glob 扩展替换错误

Bash bad substitution with glob expansion for environment variables

如何匹配包含不区分大小写的段 "proxy"(不是前缀)的环境变量?我在 bash:

root@PDPINTDEV9:~# echo ${SHELL}
/bin/bash

我想同时取消设置一堆代理变量。它们的名称中都有 "proxy" 或 "PROXY",例如 http_proxyNO_PROXY。我想使用 glob 扩展,this answer & comment says is what bash uses.

同样基于 that answer,我发现我可以找到以 "PROXY":

开头的环境变量
root@PDPINTDEV9:~# echo "${!PROXY*}"
PROXY_IP PROXY_PORT

但是 doesn't make sense with what I've read 关于全局扩展。基于这些,"${!PROXY*}" 应该匹配任何不以代理开头的东西......我认为。

此外,我无法得到任何有意义的 glob 语法来实际工作:

root@PDPINTDEV9:~# echo ${*proxy}
-bash: ${*proxy}: bad substitution
root@PDPINTDEV9:~# echo "${!*[pP][rR][oO][xX][yY]}"
-bash: ${!*[pP][rR][oO][xX][yY]}: bad substitution

已解决:事实证明你做不到。疯了,但谢谢大家。

But that doesn't make sense with what I've read about glob expansion. Based on those, "${!PROXY*}" should match anything that doesn't start with proxy... I think.

没有也没有。

首先,! 字符对路径名扩展没有意义,除非它出现在模式中字符 class 的开头,在这种情况下, class 倒置。例如,fo[!o] 是一种匹配前两个字符为 "fo" 而第三个字符不是另一个 'o' 的任何三字符字符串的模式。但是你的表达式中没有字符class。

但更重要的是,路径名扩展与您的表达式 ${!PROXY*} 完全无关。那里没有通配符。这 '!'和“*”是其中一种参数扩展形式的语法的固定部分。根据定义,那个特定的扩展产生了所有 shell 名称以 "PROXY" 开头的变量的名称,由 [= 值的第一个字符分隔15=] 变量。它出现在双引号之外的地方,它等同于 ${!PROXY@},它不太容易受到 globbing 相关混淆的影响。

Furthermore, I can't get anything that does make sense with glob syntax to actually work: [...]

不,因为,再一次,没有进行通配。您需要 ${! 后跟感兴趣的名称前缀,然后是 *}@} 以形成您要询问的特定类型的参数扩展。

How can I match environment variables which include the case-insensitive segment "proxy"?

您需要明确表达您感兴趣的案例变化。例如:

${!PROXY*} ${!proxy*} ${!Proxy*}

Variable name expansion, as a special case of shell parameter expansion,不支持 globbing。但它有两种口味:

${!PREFIX*}
${!PREFIX@}

在两者中,*@ 字符都是硬编码

第一种形式将扩展为以 PREFIX 为前缀并由 IFS(默认为 space)的第一个字符连接的变量名:

$ printf "%s\n" "${!BASH*}"
BASH BASHOPTS BASHPID BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND ...

第二种形式将扩展为变量名(前缀为PREFIX),但作为单独的词:

$ printf "%s\n" "${!BASH@}"
BASH
BASHOPTS
BASHPID
BASH_ALIASES
BASH_ARGC
...

这两种形式都是区分大小写,所以要以不区分大小写的方式获取变量名,you can use set,结合一些 cutgrep:

$ (set -o posix; set) | cut -d= -f1 | grep -i ^proxy
PROXY_IP
proxy_port