2011-12-15 43 views
40

Tôi đang đọc "Hướng dẫn Bash dành cho người mới bắt đầu". Nó nói:

Nếu ký tự đầu tiên của PARAMETER là một dấu chấm than, Bash sử dụng giá trị của biến hình thành từ phần còn lại của PARAMETER như tên của biến; biến này sau đó được mở rộng và giá trị đó được sử dụng trong phần còn lại của thay thế, thay vì giá trị của chính số PARAMETER. Điều này được gọi là mở rộng gián tiếp.

Các ví dụ đưa ra là:

franky ~> echo ${!N*} 
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH 

Tôi hoàn toàn không hiểu ở đây:

giá trị của biến hình thành từ phần còn lại của PARAMETER

Khi PARAMETER chỉ là !N*, sau đó

phần còn lại của PARAMETER

chỉ N* là. Làm thế nào điều này có thể tạo thành một biến? Bash đã tìm kiếm tất cả các lệnh có thể có?

Trả lời

56

Nếu bạn đọc trang bash người đàn ông, nó về cơ bản khẳng định những gì bạn đã nói:

Nếu ký tự đầu tiên của tham số là một dấu chấm than (!), một mức gián tiếp biến được giới thiệu. Bash sử dụng giá trị của biến được tạo thành từ phần còn lại của tham số như tên của biến; biến này sau đó được mở rộng và giá trị đó được sử dụng trong phần còn lại của thay thế, thay vì giá trị của tham số. Điều này được gọi là mở rộng gián tiếp.

Tuy nhiên, đọc trên từ đó:

Các trường hợp ngoại lệ này là các mở rộng của ${!prefix*}${!name[@]} mô tả dưới đây.

${!prefix*} Tên tiền tố trùng khớp.Mở rộng đến tên của các biến có tên bắt đầu bằng tiền tố, được phân tách bằng ký tự đầu tiên của biến đặc biệt IFS.

Nói cách khác, ví dụ cụ thể của bạn ${!N*} là một ngoại lệ quy tắc bạn trích dẫn. Nó không, tuy nhiên, làm việc như được quảng cáo trong các trường hợp dự kiến, chẳng hạn như:

$ export xyzzy=plugh ; export plugh=cave 

$ echo ${xyzzy} # normal, xyzzy to plugh 
plugh 

$ echo ${!xyzzy} # indirection, xyzzy to plugh to cave 
cave 
1

Có, nó tìm kiếm tất cả các mở rộng có thể có của các biến sau! Nếu bạn đã thực hiện:

echo ${!NP*} 

bạn sẽ chỉ nhận được NPX_PLUGIN_PATH.

Hãy xem xét ví dụ sau:

:~> export myVar="hi" 
:~> echo ${!my*} 
    myVar 
:~> export ${!my*}="bye" 
:~> echo $myVar 
    bye 
+0

các biến khác phù hợp với * cũng được đặt thành "tạm biệt"? – Anthony

+0

@Anthony Tôi đã thử nó và nếu '$ {! My *}' mở rộng thành myA, myB, myA được xuất với giá trị hiện tại của nó và myB được đặt thành "tạm biệt" và được xuất. Không phải rất hữu ích. – GKFX

1

Bạn đã trúng một ngoại lệ trong xử lý gián tiếp, mà nếu ký tự cuối cùng là *, tất cả các biến có tiền tố đã cho trước sẽ được trả lại.

+0

Vì vậy, ngoài trường hợp '*', điều này có giống với '$ {$ {VAR}}' không? – chronospoon

13

Có dường như là một ngoại lệ khi cho "gián tiếp" kết thúc bằng một *, vì nó không ở đây. Trong trường hợp này, nó cung cấp tất cả các tên biến bắt đầu với phần bạn đã chỉ định (N tại đây). Bash có thể làm điều đó bởi vì nó theo dõi các biến và biết biến nào tồn tại.

Đúng gián tiếp là thế này:
Nói rằng tôi có một $VARIABLE bộ biến để 42, và tôi có một biến khác $NAME thiết lập để VARIABLE. ${!NAME} sẽ cho tôi 42. Bạn sử dụng giá trị của một biến để cho bạn biết tên của một biến khác:

$ NAME="VARIABLE" 
$ VARIABLE=42 
$ echo ${!NAME} 
42 
+0

Wow, người biết rất dễ dàng để có được câu trả lời cho ý nghĩa của cuộc sống, vũ trụ và tất cả mọi thứ! – KomodoDave

+0

@KomodoDave Ngay bây giờ nếu chúng tôi chỉ biết câu hỏi .. – Dan