シェル変数がエクスポートされているかどうかを確認する最も簡単なスクリプト可能な方法は何ですか?


20

一部のシェルセッションでは、シェル変数が設定およびエクスポートされていない場合に警告フラグを出力できるようにします。

SET_MEが未設定またはnullの場合、プロンプトに「エラー」を出力するためにこのようなことを行うのはかなり簡単です。

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

ただし、SET_MEエクスポートせずに設定した場合、これはフラグ付けに失敗します。これは、検出できるようにするエラーです。のようなもの$(bash -c 'test -z "$SET_ME" && echo Error;')や、の出力をgreppingするのexportは簡単ですが、SET_MEエクスポートされたかどうかをテストするためにできる簡単なチェックはありますか?

非POSIX、bashのみのソリューションは完全に受け入れられます。

回答:


11

使用declareコマンドと正規表現のマッチング演算子:

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

これが私が探しているものだと思います。理論的には、たとえば、読み取り専用のエクスポートされた変数がある場合、reはより柔軟にする必要があるかもしれませんが、実際には他のtypeset属性は使用しません。
CBベイリー

いい視点ね。後世のために修正します。
-chepner

正規表現を引用しようとすると、bash 3.2以降では正規表現として機能しなくなるようです。
CBベイリー

また、矛盾-z "$1"があります。変数の値をtest_vardeclare -p名前のとおりに)渡していると仮定しています。シェル変数の名前をとる次のテストを思いつきましたtest_exported_notnull () { re='^declare -\w*x'; [[ -n $(eval echo \$$1) ]] && [[ $(declare -p "$1") =~ $re ]]; }
CBベイリー

を回避するにはeval、この最初の行を追加するだけです:var=$1を使用します[[ -z "${!var}" ]] && echo Error
chepner

4

私は質問が3年前のものであることを知っていますが、次の解決策をより簡単に見つけることができます:

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

変数がエクスポートされ、空でない値を持っている場合、答えます。


4

バッシュ4.4以降では、使用することができます${parameter@a} シェルパラメータ展開を、それがエクスポートされている場合を含め、パラメータに関する属性のリストを取得します。

以下は、${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}属性ごとに1文字です。各属性文字の意味は、declareコマンドの対応するオプション(この場合は、探したいもの)からxエクスポートされます。


Bash 4.4以降を使用している場合のベストアンサー!
アンディ

3

オプションを使用compgenして-X、変数がエクスポートされているかどうかを判断できます。

compgen -e -X "!$MAY_BE_EXPORTED_VARIABLE"

例えば:

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

互換性のあるベストアンサー!$ {parameter @ a}ソリューションの2倍以上遅いが、bash 3.2の場合にははるかに互換性がある
Andy

2

私が使用することに自分自身を辞任した場合exportgrep、最も簡単なテストは、おそらくこのようなものです。

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

または、null以外も必要な場合:

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

1
POSIX 7では、これexportは指定さexport -pれておらexportず、bash に似ていますが異なる正確なフォーマットが定義されています。しかし、bashはPOSIXを無視しexportexport -p!と同じ形式を使用しているようです。
Ciro Santilli新疆改造中心法轮功六四事件14年

1

exportパラメータなしで指定されたコマンドは、現在の環境でエクスポートした名前のリストを与えます:

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

いくつかのカットとセディングは綿毛を取り除きます:

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

エクスポートのリストがあり、さらに処理する準備ができています。


1
これは機能しexportますが、私は計画された使用が私のプロンプトにあるので、より少ない暗黙のフォークでより軽い答えを期待していました(したがって「ショートの[...] grepping 」)。
CBベイリー

@CharlesBailey:なるほど。bashのマンページでを検索することでこれに到達しexport、これが私が思いついた唯一のことでした。シェルからの助けも逃げません。exportとにかく組み込みですが、私はあなたが避けることができます疑いますgrep
DevSolar

1

私が現在考えることができる最も簡単な方法:

[ bash -c ': ${v1?}' 2>/dev/null ]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.