Tôi đã học được rằng các mở rộng tên tệp được thực hiện trước khi thực hiện lệnh khi chạy lệnh trong Bash. Nhưng khi thử các lệnh bên dưới (với tùy chọn -x):Mở rộng tên tệp trong các đối số "a = b" giống như các lệnh dựng sẵn Bash
touch foo=3 # Create a file with name "foo=3"
+ touch foo=3
declare foo=?
+ declare 'foo=?'
alias foo=*
+ alias 'foo=*'
Tôi không hiểu những gì tôi mong đợi vì foo =? và foo = * không được mở rộng đến các filename "foo = 3":
declare -p | grep 'foo=' # => foo='?'
alias | grep 'foo=' # => alias foo='*'
Nhưng nếu tôi chạy một built-in như cd hoặc một chức năng tiếp nhận chuyển nhượng như một tham số được viết bởi bản thân mình như show_rhs() { echo "${1%=*}='${1#*=}'"; }
tôi được những gì tôi mong đợi (foo =? và foo = * được mở rộng).
cd foo=? # => foo=3: Not a directory
show_rhs() foo=* # => foo='3'
Sự khác biệt duy nhất tôi có thể nhìn thấy ở đây là tuyên bố và bí danh là built-in VÀ chấp nhận chuyển nhượng như một tham số. Có vẻ như một cặp trích dẫn được thêm vào để bao gồm việc gán trước khi mở rộng tên tệp theo đầu ra của tùy chọn -x.
Nhưng nếu mở rộng tên tệp không chạy trước khi thực hiện lệnh bất kể lệnh là gì, đối số được chuyển vào khai báo và bí danh phải là foo = 3 thay vì foo =? và foo = * do sự hiện diện của tệp "foo = 3".
Vì vậy, Bash làm điều gì đó đặc biệt (có thể trích dẫn các ký tự đại diện?) Cho các đối số như "a = b" phụ thuộc vào các lệnh trước khi mở rộng tên tệp?
(môi trường của tôi: CentOS 5.8 64bit, GNU Bash 3.2.25)
Bí danh và biến tồn tại ở các không gian tên khác nhau. Bạn hoàn toàn có thể có một bí danh và một biến có cùng tên.Một biến được tạo với một phép gán đơn giản và một biến được tạo ra với 'khai báo' là cùng một điều mặc dù vậy' foo = 3; khai báo foo =? 'để bạn biến' foo' với giá trị '?'. Bạn có chắc chắn bạn nhận được các lỗi mà bạn yêu cầu cho hai dòng cuối cùng không? Bởi vì tôi không thấy làm thế nào có thể. Cả hai bối cảnh đó sẽ không đánh giá các biến (và thứ hai không phải là một dòng shell hợp lệ và sẽ cho bạn một lỗi về một mã thông báo không mong muốn). –
Xin lỗi vì sự nhầm lẫn. Tôi không có nghĩa là nếu có thể tạo một biến và bí danh có cùng tên. Tôi có nghĩa là cả hai foo =? và foo = * nên được mở rộng thành foo = 3 do sự hiện diện của tệp "foo = 3" trước khi được chuyển vào các lệnh đó, vì vậy cả biến và bí danh được cho là có giá trị "3" thay vì gốc ký tự đại diện. Mã khai báo và bí danh chỉ là các ví dụ. – ebk
Ah, ok. Tôi gần như nhận xét về một tập tin 'foo = 3' nhưng nghĩ rằng đó là không (và bạn đã không đề cập đến trong bài viết). Nhưng có, tôi nghĩ rằng đoán của bạn có thể là chính xác. Thực tế là những người được xây dựng trong chấp nhận các bài tập trực tiếp có nghĩa là hành vi mở rộng glob bình thường khác không xảy ra ở đó. (Nó cũng không xảy ra với 'foo =?'.) Có lẽ có gì đó trong thông số POSIX về điều này. Tôi có thể thử nhìn sau. –