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