Bash 3 không có mảng liên kết, vì vậy bạn sẽ phải sử dụng một số tính năng ngôn ngữ khác cho mục đích của mình. Lưu ý rằng ngay cả dưới bash 4, mã bạn viết không làm những gì bạn yêu cầu: ./script.sh ${ARG}
không chuyển mảng kết hợp vào tập lệnh con, vì ${ARG}
mở rộng thành không có gì khi ARG
là mảng liên kết. Bạn không thể vượt qua một mảng kết hợp với một tiến trình con, bạn cần phải mã hóa nó.
Bạn cần xác định một số giao thức truyền giao thức giữa tập lệnh mẹ và tập lệnh con. Một thông thường là chuyển các đối số trong biểu mẫu key=value
. Điều này giả định rằng ký tự =
không xuất hiện trong khóa.
Bạn cũng cần tìm ra cách trình bày mảng kết hợp trong tập lệnh mẹ và trong tập lệnh con. Họ không cần sử dụng cùng một biểu diễn.
Phương pháp phổ biến để biểu diễn mảng liên kết là sử dụng các biến riêng cho từng phần tử, với tiền tố đặt tên chung. Điều này đòi hỏi rằng tên khóa chỉ bao gồm các chữ cái ASCII (của cả hai trường hợp), chữ số và dấu gạch dưới. Ví dụ: thay vì ${myarray[key]}
, hãy viết ${myarray__key}
. Nếu khóa được xác định tại thời gian chạy, bạn cần một vòng mở rộng đầu tiên: thay vì ${myarray[$key]}
, viết
n=myarray__${key}; echo ${!n}
Đối với chuyển nhượng, sử dụng printf -v
. Lưu ý định dạng %s
thành printf
để sử dụng giá trị được chỉ định. Không viết printf -v "myarray__${key}" %s "$value"
vì điều đó sẽ xử lý $value
dưới dạng định dạng và thực hiện mở rộng printf %
mở rộng trên đó.
printf -v "myarray__${key}" %s "$value"
Nếu bạn cần phải vượt qua một mảng kết hợp biểu diễn như thế này để một quá trình con với các đại diện key=value
cãi nhau, bạn có thể sử dụng ${!myarray__*}
liệt kê trên tất cả các biến có tên bắt đầu bằng myarray__
.
args=()
for k in ${!myarray__*}; do
n=$k
args+=("$k=${!n}")
done
Trong quá trình trẻ em, để chuyển đổi đối số có dạng key=value
để biến tách với một tiền tố:
for x; do
if [[ $x != *=* ]]; then echo 1>&2 "KEY=VALUE expected, but got $x"; exit 120; fi
printf -v "myarray__${x%%=*}" %s "${x#*=}"
done
Bằng cách này, bạn có chắc rằng đây là những gì bạn cần? Thay vì gọi một tập lệnh bash từ tập lệnh bash khác, bạn có thể muốn chạy tập lệnh con trong một phiên bản con thay thế. Bằng cách đó nó sẽ kế thừa từ tất cả các biến của phụ huynh.
Vì bash 3 có mảng bình thường, bạn sẽ chỉ phải triển khai các mảng kết hợp dựa trên chúng. Nhưng nghiêm túc, tại sao điều đó lại cần thiết? –
Vui lòng xem [BashFAQ/006] (http://mywiki.wooledge.org/BashFAQ/006). –