Tôi đang viết một kịch bản và tôi phát hiện ra một số hành vi bất ngờ của các biến mảng chưa được khởi tạo và chưa đặt mà tôi không hiểu.
Trước hết, độ dài:
$ echo ${#notset[@]}
0
$ uninitialized=
$ echo ${#uninitialized[@]}
1
Tại sao lại là uninitialized
chiều dài 1? Nó có nên bằng không? Có phải vì một biến null được coi là một mảng của một phần tử null?
Thực tế này dẫn đến một số vấn đề. Ví dụ: giả sử tôi muốn tạo một mảng và chèn một số thứ nhất định dựa trên các đối số dòng lệnh của người dùng. Tôi nghĩ rằng tôi có thể làm một cái gì đó như (+) :
myarray=
if [ some-condition ]
then
myarray[${#myarray[@]}]=some-value
fi
if [ some-condition2 ]
then
myarray[${#myarray[@]}]=some-value2
elif [ some-condition3 ]
then
myarray[${myarray[@]}]=some-value3
myarray[${myarray[@]}]=some-value4
fi
Nhưng điều này để lại vị trí đầu tiên thành null, điều mà tôi không thích và cũng phá vỡ một số mã mà tôi đã viết (*) và tại thời điểm này, giả sử rằng tôi muốn xem liệu mảng đó có chứa phần tử nào không. Tôi nên làm thế nào?
[ -z "${myarray[@]}" ]
Tăng lỗi nếu mảng chứa nhiều hơn một phần tử.
[ -z "$myarray" ]
Thất bại vì phần tử đầu tiên là null, ngay cả khi mảng không trống.
Vì vậy, làm thế nào tôi nên kiểm soát rằng một mảng là chưa được khởi tạo?
Và ai đó có thể giải thích chính xác những gì xảy ra khi xử lý các mảng và unset - các biến chưa được khởi tạo?
(+) Tôi biết rằng tôi có thể tránh "khai báo" biến và nó sẽ hoạt động, nhưng tập lệnh này sẽ được xem xét bởi một giáo sư và anh ấy không thích các biến được xác định tại các vị trí ngẫu nhiên.
(*) Trước khi thử điều này, tôi đã giữ độ dài của mảng trong một biến khác và vì vậy tôi không gặp vấn đề gì. Nhưng tôi muốn tránh việc xác định các biến phụ trợ này vì tôi biết tôi có thể có được độ dài mà không cần chúng.
uninitialized
là chưa được khởi tạo; phần tử đầu tiên của nó là chuỗi rỗng.foo
và${foo[0]}
gần như có thể hoán đổi cho nhau.