Bash, kể từ phiên bản 4.3, feb 2014 (?), Có hỗ trợ rõ ràng cho các biến tham chiếu hoặc tham chiếu tên (namerefs), ngoài "eval", với hiệu suất và hiệu ứng gián tiếp có lợi tương tự, và có thể rõ ràng hơn trong các tập lệnh của bạn và cũng khó hơn để "quên" eval "và phải sửa lỗi này":
declare [-aAfFgilnrtux] [-p] [name[=value] ...]
typeset [-aAfFgilnrtux] [-p] [name[=value] ...]
Declare variables and/or give them attributes
...
-n Give each name the nameref attribute, making it a name reference
to another variable. That other variable is defined by the value
of name. All references and assignments to name, except for⋅
changing the -n attribute itself, are performed on the variable
referenced by name's value. The -n attribute cannot be applied to
array variables.
...
When used in a function, declare and typeset make each name local,
as with the local command, unless the -g option is supplied...
và cũng:
THÔNG SỐ
Một biến có thể được gán thuộc tính nameref bằng cách sử dụng tùy chọn -n cho các lệnh khai báo hoặc lệnh dựng sẵn cục bộ (xem mô tả khai báo và cục bộ bên dưới) để tạo nameref hoặc tham chiếu đến biến khác. Điều này cho phép các biến được thao tác gián tiếp. Bất cứ khi nào biến nameref được tham chiếu hoặc gán cho, thao tác thực sự được thực hiện trên biến được chỉ định bởi giá trị của biến nameref. Một nameref thường được sử dụng trong các hàm shell để chỉ một biến có tên được truyền dưới dạng đối số cho hàm. Chẳng hạn, nếu một tên biến được truyền cho hàm shell làm đối số đầu tiên của nó, thì chạy
declare -n ref=$1
bên trong hàm tạo ra một biến nameref ref có giá trị là tên biến được truyền làm đối số đầu tiên. Tài liệu tham khảo và bài tập cho ref được coi là tài liệu tham khảo và bài tập cho biến có tên được chuyển là 1 $. Nếu biến điều khiển trong vòng lặp for có thuộc tính nameref, danh sách các từ có thể là danh sách các biến shell và tham chiếu tên sẽ được thiết lập cho mỗi từ trong danh sách, lần lượt, khi vòng lặp được thực thi. Biến mảng không thể được cho thuộc tính -n. Tuy nhiên, các biến nameref có thể tham chiếu các biến mảng và biến mảng được đăng ký. Namerefs có thể được hủy đặt bằng cách sử dụng tùy chọn -n cho phần dựng sẵn chưa đặt. Mặt khác, nếu unset được thực thi với tên của biến nameref làm đối số,
Ví dụ ( EDIT 2 : (cảm ơn Ron) đã đặt tên (tiền tố) tên biến nội bộ hàm, để giảm thiểu xung đột biến ngoài, cuối cùng sẽ trả lời đúng, vấn đề được nêu trong các nhận xét của Karsten):
# $1 : string; your variable to contain the return value
function return_a_string () {
declare -n ret=$1
local MYLIB_return_a_string_message="The date is "
MYLIB_return_a_string_message+=$(date)
ret=$MYLIB_return_a_string_message
}
và thử nghiệm ví dụ này:
$ return_a_string result; echo $result
The date is 20160817
Lưu ý rằng bash "khai báo" dựng sẵn, khi được sử dụng trong một hàm, làm cho biến khai báo là "cục bộ" theo mặc định và "-n" cũng có thể được sử dụng với "cục bộ".
Tôi thích phân biệt các biến "khai báo quan trọng" với các biến "nhàm chán cục bộ", vì vậy sử dụng "khai báo" và "cục bộ" theo cách này đóng vai trò là tài liệu.
EDIT 1 - (Trả lời nhận xét bên dưới của Karsten) - Tôi không thể thêm nhận xét bên dưới nữa, nhưng nhận xét của Karsten khiến tôi suy nghĩ, vì vậy tôi đã thực hiện bài kiểm tra sau đây WORKS FINE, AFAICT - Karsten nếu bạn đọc điều này, vui lòng cung cấp một bộ chính xác trong số các bước kiểm tra từ dòng lệnh, hiển thị sự cố mà bạn cho là tồn tại, bởi vì các bước sau hoạt động tốt:
$ return_a_string ret; echo $ret
The date is 20170104
(Tôi đã chạy nó ngay bây giờ, sau khi dán hàm trên vào một thuật ngữ bash - như bạn có thể thấy, kết quả hoạt động tốt.)
function funcName {
là cú pháp kế thừa tiền POSIX được kế thừa từ ksh đầu tiên (nơi nó có sự khác biệt về ngữ nghĩa mà bash không tôn vinh).funcName() {
, với khôngfunction
, nên được sử dụng thay thế; xem wiki.bash-hackers.org/scripting/obsolete