Bir kabuk değişkeninin dışa aktarılıp aktarılmadığını kontrol etmenin en basit komut dosyası nedir?


20

Bazı kabuk oturumları için, bir kabuk değişkeni ayarlanıp dışa aktarılmazsa bir uyarı bayrağı yazdırabilirim.

SET_MEAyarlanmamış veya boşsa , istemde "Hata" yazdırmak için böyle bir şey yapmak oldukça basittir .

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

SET_MEDışa aktarmadan ayarladığımda işaretlemek başarısız olur , bu da algılamak istediğim bir hatadır. Kısa bir $(bash -c 'test -z "$SET_ME" && echo Error;')çıktı veya selamlamak gibi bir şey export, SET_MEihraç olup olmadığını test etmek için yapabileceğim basit bir kontrol var mı ?

POSIX olmayan, sadece bash çözümü tamamen kabul edilebilir.

Yanıtlar:


11

Kullanım declarekomuta ve düzenli ifade eşleşen operatörünü:

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

Aradığım şey bu. Teorik olarak, re'nin daha esnek olması gerekebilir, örneğin, salt okunur bir değişkenim olsaydı, ama pratikte asla başka typesetnitelikler kullanmam .
CB Bailey

İyi bir nokta. Bunu gelecek nesiller için düzeltirim.
chepner

Normal ifadeyi alıntılamaya çalışmak, bash> = 3.2'de normal ifade olarak çalışmasını durdurur gibi görünüyor.
CB Bailey

Ayrıca bir tutarsızlık var, -z "$1"bir değişkenin değerini test_var(benim gibi) declare -pgeçirirken, onun adını beklediğini varsayar . Ben bir kabuk değişkeninin adını alır bu testin ile geldi: test_exported_notnull () { re='^declare -\w*x'; [[ -n $(eval echo \$$1) ]] && [[ $(declare -p "$1") =~ $re ]]; }.
CB Bailey

Bundan kaçınmak için evalşu ilk satırı ekleyin:, var=$1sonra kullanın [[ -z "${!var}" ]] && echo Error.
chepner

4

Sorunun 3 yaşında olduğunu biliyorum, ancak aşağıdaki çözümü daha basit bulabiliriz:

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

değişken dışa aktarılırsa ve boş olmayan bir değere sahipse yanıt verir.


4

In Bash 4.4 veya sonrası kullanabileceğiniz ${parameter@a} kabuk parametresi genişlemesini o ihraç edenler de dahil, bir parametre hakkında özelliklerin bir listesini almak için.

Aşağıda, ${parameter@a}adı verilen belirli bir değişkenin dışa aktarılıp aktarılmadığını gösteren basit bir işlev gösterilmektedir :

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

Kullanım örneği:

$ 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.

Nasıl çalışır:

Tarafından döndürülen biçim ${parameter@a}, özellik başına bir karakterdir ve declare komutundaki karşılık gelen seçeneklerden gelen her özellik karakterinin anlamı - bu durumda, aramak istiyoruz x- dışa aktarılır.


Bash 4.4 veya daha yenisini kullanıyorsanız En İyi Cevap!
Andy

3

Bir değişkenin dışa aktarılıp aktarılmadığını belirlemek compgeniçin -Xseçeneğiyle birlikte kullanabilirsiniz :

compgen -e -X "!$MAY_BE_EXPORTED_VARIABLE"

Örneğin:

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

En uyumlu cevap! $ {Parametre @ a} çözümünden iki kat daha yavaş, ancak bash 3.2 vakaları için çok daha uyumlu
Andy

2

Kendimi kullanmak zorunda kaldım exportve grepen basit test muhtemelen böyle bir şey.

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

ya da ben null olmayan isterseniz:

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

1
POSIX 7, bunun exportbelirtilmediğini ve bash'a export -pbenzer exportancak farklı için kesin bir format tanımladığını söylüyor . Ama bash POSIX görmezden ve aynı biçimi kullanın görünüyor exportiçin export -p!
Ciro Santilli 事件 改造: 法轮功 六四 事件

1

exportParametreler olmadan verilen komut, mevcut ortamda ihraç isim listesini verir:

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

Bazı kesme ve sedme tüylerden kurtulur:

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

Daha fazla işleme hazır, ihracat listeniz var.


1
Bu işe yarıyor ama exportplanlanan kullanım istemimde olduğu gibi daha az ima edilen çatalla (dolayısıyla "Kısa [...] çıkışını selamlayan ") daha hafif bir cevap bekliyordum .
CB Bailey

@CharlesBailey: Anlıyorum. Buraya bash manpage'i arayarak exportgeldim ve bulduğum tek şey buydu. Kabuktan hiçbir yardım da kaçmaz. exportNeyse yerleşiğidir, ama önleyebilirsiniz şüphe grep.
DevSolar

1

Şu anda düşünebildiğim en basit yöntem:

[ bash -c ': ${v1?}' 2>/dev/null ]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.