Tùy thuộc vào tình huống chính xác, điều này là không xác định rõ ràng (vì vậy việc triển khai có thể làm như họ muốn) hoặc bắt buộc phải xảy ra như bạn quan sát. Trong kịch bản chính xác của bạn echo ab$
, POSIX bắt buộc đầu ra "ab $" mà bạn quan sát thấy và nó không phải là không xác định . Một bản tóm tắt nhanh chóng của tất cả các trường hợp khác nhau là ở cuối.
Có hai yếu tố: đầu tiên mã thông báo thành các từ và sau đó giải thích các từ đó.
Mã thông báo
POSIX tokenisation đòi hỏi một $
đó không phải là sự bắt đầu của một giá trị mở rộng tham số , thay thế lệnh , hoặc thay số học được coi là một phần đen của WORD
con người dấu hiệu xây dựng. Điều này là do quy tắc 5 ("Nếu ký tự hiện tại là không được trích dẫn $
hoặc `
, trình bao sẽ xác định bắt đầu của bất kỳ ứng cử viên nào để mở rộng tham số, thay thế lệnh hoặc mở rộng số học từ các chuỗi ký tự không được trích dẫn giới thiệu của chúng: $
hoặc ${
, $(
hoặc `
, và $((
, tương ứng" ) không áp dụng, vì không có bất kỳ mở rộng nào là khả thi ở đó. Mở rộng tham số yêu cầu một tên hợp lệ xuất hiện ở đó và một tên trống không hợp lệ.
Vì quy tắc này không được áp dụng, chúng tôi tiếp tục theo dõi cho đến khi tìm thấy quy tắc đó. Hai ứng cử viên là # 8 ("Nếu ký tự trước là một phần của từ, ký tự hiện tại sẽ được thêm vào từ đó.") Và # 10 ("Ký tự hiện tại được sử dụng làm từ bắt đầu của một từ mới.") , áp dụng cho echo a$
và echo $
tương ứng.
Ngoài ra còn có trường hợp thứ ba của biểu mẫu echo a$+b
rơi vào cùng vết nứt, vì đó +
không phải là tên của một tham số đặc biệt. Cái này chúng ta sẽ quay lại sau, vì nó kích hoạt các phần khác nhau của quy tắc.
Do đó, đặc điểm kỹ thuật yêu cầu rằng $
được coi là một phần của từ cú pháp, và sau đó nó có thể được xử lý thêm sau này.
Mở rộng từ
Sau khi đầu vào được phân tích cú pháp theo cách này, với từ được $
bao gồm trong từ, mở rộng từ được áp dụng cho từng từ đã được đọc. Mỗi từ được xử lý riêng .
Nó được chỉ định rằng :
Nếu một '$' không được trích dẫn được theo sau bởi một ký tự không phải là một trong những điều sau đây:
- Một ký tự số
- Tên của một trong các tham số đặc biệt (xem Thông số đặc biệt )
- Một ký tự đầu tiên hợp lệ của một tên biến
- A
<left-curly-bracket>
('{')
- Một
<left-parenthesis>
kết quả là không xác định.
"Không xác định" là một thuật ngữ cụ thể ở đây có nghĩa là
- Một vỏ phù hợp có thể chọn bất kỳ hành vi nào trong trường hợp này
- Một ứng dụng phù hợp không thể dựa vào bất kỳ hành vi cụ thể nào
Trong ví dụ của bạn, echo ab$
thì $
không được theo sau bởi bất kỳ nhân vật , vì vậy quy định này không áp dụng và kết quả không xác định không gọi. Đơn giản là không có sự mở rộng nào được kích hoạt bởi $
, vì vậy nó thực sự có mặt và được in ra.
Trường hợp sẽ áp dụng là trong trường hợp thứ ba của chúng tôi từ trên : echo a$+b
. Dưới đây $
là tiếp theo +
, mà không phải là một con số, tham số đặc biệt ( @
, *
, #
, ?
, -
, $
, !
, hay 0
), hãy bắt đầu của một biến tên (gạch dưới hoặc một chữ cái từ bộ ký tự xách tay ), hoặc một trong các dấu ngoặc đơn. Trong trường hợp này, hành vi không được chỉ định: vỏ tuân thủ được phép phát minh ra một tham số đặc biệt được gọi là +
mở rộng và ứng dụng tuân thủ không nên cho rằng vỏ không có . Shell có thể làm bất cứ điều gì khác mà nó thích, bao gồm báo cáo lỗi.
Ví dụ: zsh, bao gồm trong chế độ POSIX của nó, diễn giải $+b
là "được b
đặt biến " và thay thế 1 hoặc 0 ở vị trí của nó. Nó tương tự có phần mở rộng cho ~
và =
. Đây là hành vi phù hợp.
Một nơi khác điều này có thể xảy ra là echo "a$ b"
. Một lần nữa, shell được phép làm theo ý muốn và bạn với tư cách là tác giả kịch bản sẽ thoát khỏi $
nếu bạn muốn đầu ra theo nghĩa đen. Nếu bạn không, nó có thể hoạt động, nhưng bạn không thể dựa vào nó. Đây là chữ cái tuyệt đối của đặc tả, nhưng tôi không nghĩ loại chi tiết này được dự định hoặc xem xét.
Tóm tắt
echo ab$
: đầu ra theo nghĩa đen, được chỉ định đầy đủ
echo a$ b
: đầu ra theo nghĩa đen, được chỉ định đầy đủ
echo a$ b$
: đầu ra theo nghĩa đen, được chỉ định đầy đủ
echo a$b
: mở rộng tham số b
, được chỉ định đầy đủ
echo a$-b
: mở rộng tham số đặc biệt -
, được chỉ định đầy đủ
echo a$+b
: hành vi không xác định
echo "a$ b"
: hành vi không xác định
Đối với $
phần cuối của một từ, bạn được phép dựa vào hành vi và nó phải được xử lý theo nghĩa đen và được truyền cho echo
lệnh như một phần của đối số. Đó là một yêu cầu phù hợp trên vỏ.
$
đạt được ý nghĩa đặc biệt nếu đó là ký tự cuối cùng trong một từ không?" Không có ý nghĩa đặc biệt duy nhất được gán cho$
; nó được sử dụng để giới thiệu nhiều, nhưng khác biệt, mở rộng, như mở rộng tham số${...}
, thay thế lệnh$(...)
và biểu thức số học$((...))
. Một số shell giới thiệu các bối cảnh bổ sung, nhưksh
biến thể thay thế lệnhx=${ echo foo; echo bar;}
(khác với tiêu chuẩn$(...)
bằng cách không thực hiện các lệnh trong một lớp con).