यह जांचने का सबसे सरल तरीका है कि शेल चर निर्यात किया जाता है या नहीं?


20

कुछ शेल सत्रों के लिए मैं एक चेतावनी ध्वज प्रिंट करने में सक्षम होना चाहता हूं यदि शेल चर सेट नहीं किया जाता है और निर्यात किया जाता है।

यदि आप परेशान SET_MEया अशक्त हैं, तो प्रॉम्प्ट में "त्रुटि" प्रिंट करने के लिए इस तरह का कुछ करना काफी सरल है ।

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निर्यात किया गया है?

एक गैर-पॉसिक्स, बैश-केवल समाधान पूरी तरह से स्वीकार्य है।

जवाबों:


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
}

मुझे लगता है कि यह वही है जिसकी मुझे तलाश है। सिद्धांत रूप में, री को और अधिक लचीला होने की आवश्यकता हो सकती है, उदाहरण के लिए अगर मेरे पास केवल-पढ़ने के लिए निर्यात किया गया चर है, लेकिन व्यवहार में मैं कभी अन्य typesetविशेषताओं का उपयोग नहीं करता ।
CB बेली

अच्छी बात। मैं इसे पश्चाताप के लिए ठीक करूंगा।
Chepner

यह ऐसा प्रतीत होता है कि नियमित अभिव्यक्ति को उद्धृत करने का प्रयास करना इसे बैश> = 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 ]]; }:।
सीबी बेली

से बचने के लिए eval, बस इस पहली पंक्ति को जोड़ें: var=$1फिर उपयोग करें [[ -z "${!var}" ]] && echo Error
चेपनर

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निर्यात करना चाहते हैं ।


सर्वश्रेष्ठ जवाब अगर आप बैश 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

सबसे अच्छा संगत जवाब! $ {पैरामीटर @ a} सॉल्यूशन से दोगुना, लेकिन बैश 3.2 मामलों के लिए कहीं अधिक संगत
एंडी

2

अगर मैंने अपने आप को इस्तेमाल करने के लिए इस्तीफा दे दिया है exportऔर grep, सबसे सरल परीक्षा शायद कुछ इस तरह है।

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

या अगर मुझे गैर-अशक्त भी चाहिए:

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

1
POSIX 7 कहता है कि exportअनिर्दिष्ट है, और export -pबैश के समान exportलेकिन अलग के लिए एक सटीक प्रारूप को परिभाषित करता है । लेकिन बैश POSIX को नजरअंदाज करता है और उसी प्रारूप का उपयोग करता exportहै export -p!
सिरो सेंटिल्ली 新疆 改造 i i 事件 '16

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") क्योंकि मेरा नियोजित उपयोग मेरे संकेत में है।
CB Bailey

@CharlesBailey: मैं देख रहा हूं। मैं इसके लिए bash manpage सर्च करके आया export, और यही एक चीज थी जिसके साथ मैं आया था। शेल से कोई मदद भी नहीं बचती है। exportवैसे भी अंतर्निहित है, लेकिन मुझे शक है आप बच सकते हैं grep
DevSolar

1

सबसे आसान तरीका जो मैं वर्तमान में सोच सकता हूं:

[ bash -c ': ${v1?}' 2>/dev/null ]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.