检查是否导出shell变量的最简单的脚本方法是什么?


18

对于某些shell会话,如果未设置和导出shell变量,我希望能够打印警告标志。

做这样的事情在提示中打印“错误”是相当简单的 SET_ME 未设置或为空。

test_var () { test -z "$1" && echo Error; }
PS1='$(test_var "$SET_ME") \$ '

但是,如果我设置,则无法标记 SET_ME 没有导出它,这是我想要检测的错误。缺少类似的东西 $(bash -c 'test -z "$SET_ME" && echo Error;') 或者打算输出 export,有没有一个简单的检查,我可以做测试是否 SET_ME 已出口?

非POSIX,仅限bash的解决方案是完全可以接受的。

Answers:


10

使用 declare 命令和正则表达式匹配运算符:

test_var () {
    # $1 - name of a shell variable
    var=$1
    [[ -z "${!var}" ]] && echo Error
    [[ $(declare -p $1)  =~ ^declare\ -[aAilrtu]*x[aAilrtu]*\  ]] || echo Error
}

我认为这就是我要找的东西。从理论上讲,可能需要更灵活,例如如果我有一个只读导出变量,但在实践中我从不使用其他变量 typeset 属性。
CB Bailey

好点子。我会为子孙后代修理它。
chepner

看起来试图引用正则表达式会使它在bash> = 3.2中作为正则表达式停止工作。
CB Bailey

还有一个不一致的地方, -z "$1" 假设我将变量的值传递给 test_var (就像我一样)而 declare -p 期待它的名字。我想出了这个带有shell变量名称的测试: test_exported_notnull () { re='^declare -\w*x'; [[ -n $(eval echo \$$1) ]] && [[ $(declare -p "$1") =~ $re ]]; }
CB Bailey

避免 eval,只需添加第一行: var=$1,然后使用 [[ -z "${!var}" ]] && echo Error
chepner

4

我知道这个问题已经有3年了,但是可能会发现以下解决方案更简单:

[ "$(bash -c 'echo ${variable}')" ]

如果变量已导出且具有非空值,则为答案。


2

如果我让自己不得不使用 exportgrep,最简单的测试可能是这样的。

export | grep -Eq '^declare -x SET_ME='

或者如果我也想要非null:

export | grep -Eq '^declare -x SET_ME=".+"'

1
POSIX 7说 export 未指定,并定义了精确的格式 export -p 类似于bash export 但不同。但bash似乎忽略了POSIX并使用相同的格式 export 对于 export -p
Ciro Santilli 新疆改造中心 六四事件 法轮功

2

您可以使用 compgen 用它 -X 确定是否导出变量的选项:

compgen -e -X "!$MAY_BE_EXPORTED_VARIABLE"

例如。:

$ NOT_EXPORTED="xxx"
$ compgen -e -X '!SHELL'
SHELL
$ compgen -e -X '!NOT_EXPORTED'
$ echo $?
1

2

Bash 4.4或更高版本 ,你可以使用 ${parameter@a} shell参数扩展 获取有关参数的属性列表,包括是否已导出。

这是一个简单的功能演示 ${parameter@a},这将告诉您是否导出给定变量,给定其名称:

function is_exported {
    local name="$1"
    if [[ "${!name@a}" == *x* ]]; then
        echo "Yes - '$name' is exported."
    else
        echo "No - '$name' is not exported."
    fi
}

使用示例:

$ is_exported PATH
Yes - 'PATH' is exported.
$ foo=1 is_exported foo
Yes - 'abc' is exported.
$ bar=1; is_exported bar
No - 'abc' is not exported.
$ export baz=1; is_exported baz
Yes - 'baz' is exported.
$ export -n baz; is_exported baz
No - 'baz' is not exported.
$ declare -x qux=3; is_exported qux
Yes - 'qux' is exported.

这个怎么运作:

返回的格式 ${parameter@a} 每个属性是一个字符,每个属性字符的含义来自于相应的选项 声明命令 - 在这种情况下,我们想要寻找 x - 出口。


1

export 在没有参数的情况下给出的命令给出了当前环境中导出的名称列表:

$ FOO1=test
$ FOO2=test
$ export | grep FOO
$ export FOO2
$ export | grep FOO
declare -x FOO2="test"

一些切割和sed'ing摆脱了绒毛:

export | cut -d' ' -f 3- | sed s/=.*//

这是您的出口清单,可供进一步处理。


1
这确实有效,但我希望用更少的隐含叉子来获得更轻松的答案(因此“没有...” export “)因为我的计划用途是在我的提示中。
CB Bailey

@CharlesBailey:我明白了。我通过搜索bash手册来找到它 export,这是我想出的唯一一件事。 shell的帮助也没有逃脱。该 export 无论如何都是内置的,但我怀疑你可以避免 grep
DevSolar

1

我目前可以想到的最简单的方法:

[ bash -c ': ${v1?}' 2>/dev/null ]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.