2013-06-19 25 views
38

Tôi vừa phát hiện ra về các tùy chọn extglob vỏ bash đây: - How can I use inverse or negative wildcards when pattern matching in a unix/linux shell?Tại sao tôi không để extglob được kích hoạt trong bash?

Tất cả các câu trả lời mà dùng shopt -s extglob cũng đề cập đến shopt -u extglob để tắt nó đi. Tại sao tôi muốn biến cái gì đó hữu ích? Thật vậy tại sao không phải là nó theo mặc định? Có lẽ nó có tiềm năng cho một số bất ngờ khó chịu. Chúng là gì?

Trả lời

35

Không có bất ngờ khó chịu - hành vi mặc định tắt chỉ có ở đó để tương thích với cú pháp mẫu truyền thống, tuân thủ tiêu chuẩn.


Đó là để nói: Có thể (mặc dù không chắc) mà người viết fo+(o).*thực sự có ý định các + và ngoặc được đối xử như các bộ phận đen của mô hình kết hợp bởi mã của họ. Đối với bash để diễn giải biểu thức này theo cách khác với thông số POSIX sh sẽ là phá vỡ tính tương thích, được thực hiện theo mặc định trong rất ít trường hợp (echo -e với xpg_echo không được đặt là chỉ có ý tưởng ngay lập tức) .

Điều này khác với trường hợp thông thường khi mở rộng bash là hành vi mở rộng không xác định theo tiêu chuẩn POSIX - trường hợp vỏ POSIX cơ sở thường ném lỗi, nhưng thay vào đó, bash cung cấp một số hành vi được ghi lại mới và khác - bởi vì sự cần thiết phải xử lý các ký tự này giống như chúng được xác định bởi POSIX.

Để báo the relevant part of the specification, với sự nhấn mạnh thêm:

Một nhân vật bình thường là một mô hình đó sẽ phù hợp với bản thân. Có thể là bất kỳ ký tự nào trong bộ ký tự được hỗ trợ ngoại trừ NUL, các ký tự đặc biệt trong Quoting yêu cầu trích dẫn và ba ký tự mẫu đặc biệt sau. Kết hợp phải dựa trên mẫu bit được sử dụng để mã hóa ký tự, không phải trên biểu diễn đồ họa của ký tự. Nếu bất kỳ ký tự nào (thông thường, đặc biệt vỏ hoặc mẫu đặc biệt) được trích dẫn, mẫu đó phải khớp với chính ký tự đó. Các ký tự đặc biệt của shell luôn yêu cầu trích dẫn.

Khi không thể viện chứng và bên ngoài một biểu thức khung, ba nhân vật dưới đây được ý nghĩa đặc biệt trong đặc tả của mô hình:

  • ? - Một dấu hỏi là một mô hình đó sẽ phù hợp với bất kỳ ký tự.
  • * - Dấu hoa thị là mẫu phải khớp với nhiều ký tự, như được mô tả trong Patterns Matching Multiple Characters.
  • [ - Khung mở phải giới thiệu biểu thức khung mẫu.

Vì vậy, tiêu chuẩn đòi hỏi một cách rõ ràng bất kỳ ký tự phi NUL khác hơn ?, * hoặc [ hoặc những người được liệt kê ở những nơi khác như yêu cầu trích dẫn để phù hợp với bản thân. Hành vi của Bash khi tắt extglob theo mặc định cho phép nó phù hợp với tiêu chuẩn này trong cấu hình mặc định của nó.


Tuy nhiên, đối với kịch bản của riêng bạn và vỏ tương tác của riêng bạn, trừ khi bạn đang thực hiện một thói quen chạy mã viết cho POSIX sh với các mẫu bất thường bao gồm, cho phép extglob thường là giá trị thực hiện.

+7

Giá trị/an toàn để đặt trong .bashrc của tôi? – hardcode57

+5

@ hardcode57 Có. –

2

Là người Kornshell, tôi có extglob ở trong số .bashrc theo mặc định vì đó là cách thực hiện trong Kornshell và tôi sử dụng nó rất nhiều.

Ví dụ:

$ find !(target) -name "*.xml" 

Trong Kornshell, đây là không có vấn đề. Trong BASH, tôi cần đặt extglob. Tôi cũng đặt lithistset -o vi. Điều này cho phép tôi sử dụng các lệnh VI trong việc sử dụng lịch sử trình bao của mình, và khi tôi nhấn v, nó cho thấy mã của tôi là một loạt các dòng.

Without lithist thiết lập:

for i in *;do;echo "I see $i";done 

Với listhist thiết lập:

for i in * 
do 
    echo "I see $i" 
done 

Bây giờ, chỉ khi BASH đã báo cáo kết quả print, tôi muốn được tất cả các thiết lập.

+2

thay thế ưa thích của bash cho echo là một phiên bản mở rộng của 'printf', mà ksh _does_ cũng có ... –

+1

@CharlesDuffy Vâng, tôi biết về' printf'. Vấn đề của tôi là thói quen. Tôi đã viết kịch bản Kornshell từ những năm 1980. Thói quen nói khi tôi viết một kịch bản lệnh shell nhanh trên dòng lệnh, sử dụng 'print' và không phải' echo'. BASH và KSH tương thích 98%. Nó đủ để làm tôi phát điên. Tôi có thể chuyển đổi giữa các ngôn ngữ khác nhau bằng cách suy nghĩ vì cú pháp khác nhau. BASH là đủ như KSH mà tôi quên tôi đang sử dụng BASH chứ không phải KSH. Sau đó, tôi thử một Kornism như 'r vi' hoặc' cd foo bar', và BASH hân hoan từ chối nó. Grrrr ... –

+1

@DavidW. - Tôi đã chuyển đổi vài năm trước, và trước khi tôi nhận được thư viện kịch bản của mình được chuyển qua, tôi đã có rất nhiều kshisms tương thích với lỗi được thực hiện như các hàm - 'print',' whence', v.v. nạng. Sự biểu cảm của! mở rộng đã cho tôi tự hỏi làm thế nào tôi đã bao giờ có bằng 'r' /' fc'. –

Các vấn đề liên quan