สำหรับทุบตีมันเป็นการแฮ็คเล็กน้อย (แม้ว่าจะมีเอกสาร): พยายามใช้typeset
เพื่อลบแอตทริบิวต์ "array":
$ 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 )
สิ่งนี้ก็จำเป็นต้องมี subshell ด้วย
อีกหนึ่งเทคนิคที่มีประโยชน์ก็คือcompgen
:
compgen -A arrayvar
นี่จะแสดงรายการอาร์เรย์ที่จัดทำดัชนีทั้งหมดอย่างไรก็ตามอาร์เรย์ที่เชื่อมโยงไม่ได้ถูกจัดการเป็นพิเศษ (สูงสุด bash-4.4) และปรากฏเป็นตัวแปรปกติ ( compgen -A variable
)