declare -a A vytvořte prázdné pole A v bash, nebo pouze nastavuje atribut v případě A je přiřazen později?
Zvažte tento kód:
set -u
declare -a A
echo ${#A[*]}
echo ${A[*]}
A=()
echo ${#A[*]}
echo ${A[*]}
A=(1 2)
echo ${#A[*]}
echo ${A[*]}
Jaký by měl být očekávaný výstup?
V Bash 4.3.48(1) dostávám bash: A: unbound variable při dotazu na počet prvků po declare .
Tuto chybu dostávám také při přístupu ke všem prvkům.
Vím, že novější verze Bash s tím zacházejí jinak.
Přesto bych rád věděl, zda declare ve skutečnosti definuje proměnná (aby byla prázdná).
Přijatá odpověď:
To závisí na tom, zda byla odpovídající proměnná již dříve deklarována v aktuálním rozsahu (nejvyšší úrovni neboli globální nebo aktuální funkce).
Pokud nebyla deklarována v aktuálním rozsahu (a pozor, v rozsahu nejvyšší úrovně mohla být proměnná deklarována (a přiřazena) importem z prostředí), poté ji deklaruje (učiní ji lokální pro funkci, když je v rozsahu funkce), přiřadí jí typ, ale neinicializuje ji, a to ani do prázdného seznamu (declare -p a ukazuje declare -a a , nikoli declare -a a=() jako by to bylo, kdybyste jej deklarovali a/nebo přiřadili pomocí a=() ).
Pokud již byla deklarována v aktuálním rozsahu (například proto, že byla importována jako skalární proměnná z prostředí v globálním rozsahu), pak declare -a a pokusí se konvertovat do pole.
Pokud to bylo dříve skalární, stane se ([0]=value-of-the-variable) pole. Pokud to již bylo pole, zůstane nedotčeno. Pokud se jednalo o asociativní pole, selže s cannot convert associative to indexed array chyba.
Všimněte si, že declare a nepřevede pole nebo hash na skalární. bash by stejně nebyl schopen převést hash/pole na skalární. Můžete použít declare +aA a k vynucení skaláru (to by selhalo s chybou, pokud by proměnná byla dříve hash/pole v aktuálním rozsahu).
Ve vašem případě proměnná pravděpodobně ještě nebyla deklarována v aktuálním rozsahu, takže skončila deklarována, ale nebyla přiřazena, což vysvětluje, proč pokus o její rozšíření selže pod set -u .
Tento rozdíl mezi dvěma deklarovanými a přiděleno /nastavit stavy proměnné není specifický pro bash . V POSIX sh , můžete také export proměnnou nebo ji udělejte readonly aniž by to mělo hodnotu.
$ sh -uc 'unset -v var; readonly var; : "$var"'
sh: 1: var: parameter not set
Všimněte si, že unset jak zruší nastavení, tak i deklaraci proměnné. V bash , mksh a yash může obnovit proměnnou z vnějšího rozsahu.
V zsh , kromě sh emulace pomocí typeset on a proměnná deklaruje a nastaví ji na prázdnou hodnotu, pokud již nebyla nastavena nebo byla nastavena, ale pochází z jiného typu (skalární vs pole vs asociativní pole).