Nếu không có ()
, cú pháp thực sự sẽ mơ hồ.
Phải có một số cú pháp rõ ràng để xác định hàm và không thay đổi đáng kể cú pháp shell khác , nó không thể là:
do_something {
# one or more commands go here
}
Bạn đã nói điều này "không kết luận với cú pháp hiện tại của nó", nhưng thực tế là vậy! Lưu ý rằng bạn không gặp phải bất kỳ loại lỗi cú pháp nào khi bạn cố chạy dòng đầu tiên . Bạn gặp lỗi, nhưng đó không phải là lỗi về cú pháp. Dòng thứ hai, với }
, là một lỗi cú pháp, nhưng dòng đầu tiên thì không. Thay vào đó, do_something {
cố gắng chạy một lệnh được gọi do_something
và chuyển {
như một đối số cho lệnh đó:
$ do_something {
do_something: command not found
Nếu đã có một lệnh được gọi do_something
, bạn đang chạy nó. Nếu đã có một hàm được gọi do_something
, bạn đang gọi nó . Nói chung, điều quan trọng là cú pháp không rõ ràng, nhưng điều đặc biệt quan trọng là có thể xác định lại hàm mà không vô tình gọi nó thay thế. Xác định một hàm và gọi nó không giống nhau.
Làm thế nào vỏ xử lý {
và (
.
Như type {
sẽ cho bạn biết, {
là một từ khóa shell. Điều này làm cho nó thích [[
. Nếu được sử dụng trong một tình huống mà nếu không nó sẽ là một lệnh, {
mang theo ngữ nghĩa đặc biệt. Cụ thể, nó thực hiện nhóm lệnh. Tuy nhiên, trong các tình huống khác, nó có thể được sử dụng không được giải thích để biểu thị một {
ký tự theo nghĩa đen . Điều này bao gồm cả tình huống chuyển nó dưới dạng từ thứ hai hoặc tiếp theo của lệnh.
Tất nhiên, Bash có thể đã được thiết kế để đối xử {
khác với hiện tại. Tuy nhiên, cú pháp của nó sau đó sẽ không còn tương thích với trình bao POSIX và Bash sẽ không thực sự là trình bao kiểu Bourne và sẽ không thể chạy nhiều tập lệnh shell.
Ngược lại, (
là một metacharacter vỏ. Nó luôn luôn đối xử đặc biệt nếu nó xuất hiện trong một lệnh và không được trích dẫn (với '
'
, "
"
hoặc \
). Do đó, không có sự mơ hồ trong cú pháp:
do_something() {
# one or more commands go here
}
Điều đó không có nghĩa gì khác. Nếu Bash không có chức năng, thì đó sẽ là lỗi cú pháp, vì lý do tương tự echo foo(bar)
là lỗi cú pháp.
Nếu bạn thực sự không thích ()
ký hiệu thì bạn có thể sử dụng từ khóa function
và bỏ qua nó, như sudodus đề cập . Lưu ý rằng đây không phải là một phần của cú pháp để xác định các hàm trong hầu hết các shell kiểu Bourne khác - và trong một số, nó được hỗ trợ nhưng các hàm được định nghĩa theo cách đó có ngữ nghĩa khác nhau - và do đó, một tập lệnh sử dụng nó sẽ không thể di động được. (Lý do cú pháp này có thể rõ ràng là function
chính nó là một từ khóa trong Bash biểu thị rằng bất cứ điều gì theo sau nó là sự khởi đầu của một định nghĩa hàm.)
Cuối cùng, lưu ý rằng trong khi hầu hết các định nghĩa hàm sử dụng {
trong thực tế, bất kỳ lệnh ghép nào đều được phép. Nếu bạn có một chức năng mà cơ thể bạn muốn luôn luôn chạy trong một lớp con, bạn có thể sử dụng (
)
chứ không phải {
}
.