के लिए बैश , यह एक हैक (यद्यपि प्रलेखित) का एक छोटा सा है: उपयोग करने का प्रयास typeset
"सरणी" विशेषता को निकालने के लिए:
$ typeset +a BASH_VERSINFO
bash: typeset: BASH_VERSINFO: cannot destroy array variables in this way
echo $?
1
(आप ऐसा नहीं कर सकते zsh
, यह आपको एक सरणी को स्केलर में बदलने की अनुमति देता है, मेंbash
स्पष्ट रूप से निषिद्ध है।)
इसलिए:
typeset +A myvariable 2>/dev/null || echo is assoc-array
typeset +a myvariable 2>/dev/null || echo is array
या एक समारोह में, अंत में चेतावनी को देखते हुए:
function typeof() {
local _myvar="$1"
if ! typeset -p $_myvar 2>/dev/null ; then
echo no-such
elif ! typeset -g +A $_myvar 2>/dev/null ; then
echo is-assoc-array
elif ! typeset -g +a $_myvar 2>/dev/null; then
echo is-array
else
echo scalar
fi
}
typeset -g
(Bash-4.2 या बाद के) के उपयोग पर ध्यान दें , यह एक फ़ंक्शन के भीतर आवश्यक है ताकि typeset
(syn। declare
) उस तरह से काम न करे local
और जिस मान का आप निरीक्षण करने का प्रयास कर रहे हैं उसे क्लोब करें। यह फ़ंक्शन "वैरिएबल" प्रकारों को भी नहीं संभालता है, typeset -f
यदि आवश्यक हो तो आप एक और शाखा परीक्षण जोड़ सकते हैं ।
इसका उपयोग करने के लिए एक और (लगभग पूर्ण) विकल्प है:
${!name[*]}
If name is an array variable, expands to the list
of array indices (keys) assigned in name. If name
is not an array, expands to 0 if name is set and
null otherwise. When @ is used and the expansion
appears within double quotes, each key expands to a
separate word.
एक मामूली समस्या है, हालांकि, 0 की एकल उपप्रकार वाली एक सरणी उपरोक्त स्थितियों में से दो से मेल खाती है। यह कुछ ऐसा है जिसे mikeserv भी संदर्भित करता है, बैश वास्तव में एक कठिन अंतर नहीं है, और इसमें से कुछ (यदि आप चैंगेलॉग की जांच करते हैं) को ksh और संगति पर कैसे ${name[*]}
या कैसे दोषी ठहराया जा सकता है?${name[@]}
एक गैर-सरणी पर व्यवहार करते हैं।
तो एक आंशिक समाधान है:
if [[ ${!BASH_VERSINFO[*]} == '' ]]; then
echo no-such
elif [[ ${!BASH_VERSINFO[*]} == '0' ]]; then
echo not-array
elif [[ ${!BASH_VERSINFO[*]} != '0' ]];
echo is-array
fi
मैंने अतीत में इस पर भिन्नता का उपयोग किया है:
while read _line; do
if [[ $_line =~ ^"declare -a" ]]; then
...
fi
done < <( declare -p )
यह भी हालांकि एक उपधारा की जरूरत है।
एक और संभवतः उपयोगी तकनीक है compgen
:
compgen -A arrayvar
यह सभी अनुक्रमित सरणियों को सूचीबद्ध करेगा, हालांकि साहचर्य सरणियों को विशेष रूप से नियंत्रित नहीं किया जाता है (बैश-4.4 तक) और नियमित चर के रूप में दिखाई देते हैं ( compgen -A variable
)