쉘 변수의 익스포트 여부를 확인하는 가장 간단한 스크립트 가능한 방법은 무엇입니까?


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 Bailey

좋은 지적. 나는 후손을 위해 고칠 것이다.
chepner

정규 표현식을 인용하려고하면 bash> = 3.2에서 정규 표현식으로 작동하지 않습니다.
CB Bailey

또한 불일치 -z "$1"가 있습니다. 변수 값을 test_var(있는 그대로) 전달하지만 declare -p이름 은 기대 한다고 가정합니다 . 쉘 변수의 이름을 취하는이 테스트를 생각해 냈습니다 : 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}')" ]

변수가 내보내지고 비어 있지 않은 값이 있으면 응답합니다.


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}은 속성 당 하나의 문자이며, 각 속성 문자의 의미는 선언 명령 의 해당 옵션에서 나옵니다 .이 경우 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} 솔루션보다 두 배 이상 느리지 만 bash 3.2 사례와 훨씬 더 호환
Andy

2

본인이 exportand 을 사용해야한다는 사실에 사임 grep하면 가장 간단한 테스트는 아마도 다음과 같습니다.

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

또는 null이 아닌 경우 :

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

1
POSIX 7 말한다export지정하고, 대한 정확한 형식을 정의 export -pbash는 유사 export하지만 서로 다른. 그러나 배쉬는 POSIX를 무시하고 같은 형식을 사용하는 것 export을위한 export -p!
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

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계획된 사용이 나의 프롬프트에있을 때 나는 더 적은 묵시적 ​​포크 (따라서 "[Short of [...] output of " "))로 더 가벼운 대답을 원했습니다 .
CB Bailey

@CharlesBailey : 알겠습니다. 나는 bash 맨 페이지를 검색하여 이것에 왔으며 이것이 export내가 생각해 낸 유일한 것이었다. 쉘의 도움도 없습니다. 은 export어쨌든 내장,하지만 난 당신이를 방지 할 수 있습니다 의심 grep.
DevSolar

1

내가 생각할 수있는 가장 간단한 방법 :

[ bash -c ': ${v1?}' 2>/dev/null ]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.