Tôi đang dùng một cú đâm khi viết hoàn thành Bash lần đầu tiên và tôi có một chút nhầm lẫn về hai cách của dereferencing mảng Bash (${array[@]}
và ${array[*]}
).
Đây là đoạn có liên quan của mã (nó hoạt động, bằng cách này, nhưng tôi muốn hiểu nó tốt hơn):
_switch()
{
local cur perls
local ROOT=${PERLBREW_ROOT:-$HOME/perl5/perlbrew}
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
perls=($ROOT/perls/perl-*)
# remove all but the final part of the name
perls=(${perls[*]##*/})
COMPREPLY=($(compgen -W "${perls[*]} /usr/bin/perl" -- ${cur}))
}
Bash của documentation says:
Bất kỳ yếu tố của một mảng có thể được tham chiếu bằng $ {name [subscript]}. Các dấu ngoặc được yêu cầu để tránh xung đột với các toán tử mở rộng tên tệp của trình bao. Nếu chỉ số là ‘@’ hoặc ‘*’, từ đó sẽ mở rộng cho tất cả các thành viên của tên mảng. Các chỉ số này chỉ khác nhau khi từ xuất hiện trong dấu ngoặc kép. Nếu từ được trích dẫn kép, $ {name [*]} mở rộng thành một từ có giá trị của mỗi thành viên mảng được phân cách bằng ký tự đầu tiên của biến IFS và $ {name [@]} mở rộng từng phần tử của tên với một từ riêng biệt.
Bây giờ tôi nghĩ tôi hiểu rằng compgen -W
sẽ là một chuỗi có chứa một danh sách từ các lựa chọn thay thế có thể, nhưng trong bối cảnh này, tôi không hiểu những gì "$ {name [@]} mở rộng mỗi yếu tố của tên cho một từ riêng " có nghĩa.
Dài câu chuyện ngắn: ${array[*]}
hoạt động; ${array[@]}
thì không. Tôi muốn biết tại sao, và tôi muốn hiểu rõ hơn chính xác những gì chính xác ${array[@]}
mở rộng.
Điều này thật tuyệt vời; cảm ơn. Tôi thực sự muốn nó thổi lên to hơn, nhưng điều này ít nhất làm rõ lý do tại sao nó không hoạt động. – Telemachus