Tôi đang viết một tập lệnh bash có set -u
và tôi gặp sự cố với việc mở rộng mảng trống: bash dường như coi một mảng trống là một biến chưa được đặt trong quá trình mở rộng:
$ set -u
$ arr=()
$ echo "foo: '${arr[@]}'"
bash: arr[@]: unbound variable
( declare -a arr
cũng không giúp được gì.)
Một giải pháp phổ biến cho điều này là sử dụng ${arr[@]-}
thay thế, do đó thay thế một chuỗi trống thay vì mảng trống ("không xác định"). Tuy nhiên, đây không phải là một giải pháp tốt, vì bây giờ bạn không thể phân biệt giữa một mảng có một chuỗi rỗng trong đó và một mảng trống. (@ -expansion là đặc biệt trong bash, nó mở rộng "${arr[@]}"
thành "${arr[0]}" "${arr[1]}" …
, làm cho nó trở thành một công cụ hoàn hảo để xây dựng các dòng lệnh.)
$ countArgs() { echo $#; }
$ countArgs a b c
3
$ countArgs
0
$ countArgs ""
1
$ brr=("")
$ countArgs "${brr[@]}"
1
$ countArgs "${arr[@]-}"
1
$ countArgs "${arr[@]}"
bash: arr[@]: unbound variable
$ set +u
$ countArgs "${arr[@]}"
0
Vì vậy, có cách nào để giải quyết vấn đề đó, ngoài việc kiểm tra độ dài của một mảng trong một if
(xem mẫu mã bên dưới), hoặc tắt -u
cài đặt cho đoạn ngắn đó?
if [ "${#arr[@]}" = 0 ]; then
veryLongCommandLine
else
veryLongCommandLine "${arr[@]}"
fi
Cập nhật: Đã xóa bugs
thẻ do ikegami giải thích.
"${arr[@]}"
. Tui bỏ lỡ điều gì vậy? Từ những gì tôi có thể thấy nó hoạt động ít nhất trong5.x
.