Tại sao nullglob ảnh hưởng đến việc hoàn thành tab?


7

Sau đó shopt -s nullglob, tôi nhận thấy rằng việc hoàn thành tab hoàn toàn ngừng hoạt động. Tại sao lại như vậy? extglobrõ ràng là lành tính , nullglob có thể ảnh hưởng gì khác?

Quan sát trên:

  • Ubuntu 14.04 (bash 4.3.11(1)-release)
  • Arch Linux (bash 4.3.42(1)-release)

Câu trả lời:


8

Không giống như extglob, nullgloblàm cho một sự khác biệt rất lớn trong hành vi vỏ. Nó có nghĩa là một từ có chứa các ký tự đại diện có khả năng khớp với không có gì dẫn đến một từ biến mất thay vì được giữ lại.

Trong hầu hết các trường hợp, mã bị phá vỡ nullglobcũng sẽ bị phá vỡ nếu không có nó, nếu một thư mục nhất định chứa các tệp xảy ra khớp với mẫu không trích dẫn. Tùy thuộc vào mẫu, sự tồn tại của các tệp như vậy có thể ít nhiều có khả năng (và có thể là không thể nếu các tập lệnh kiểm soát tên tệp hiện diện, ví dụ vì nó chuyển sang một thư mục tạm thời mà nó cư trú).

Theo mặc định, việc hoàn thành tab của Bash không bị ảnh hưởng bởi nullglob, nhưng nó bị ảnh hưởng nếu bạn bật hoàn thành lập trình, bởi vì một số mã bash thực hiện hoàn thành lập trình không mạnh mẽ.

Nhìn vào những gì xảy ra khi hoàn thành đối số lsvới set -xbật, tôi thấy rằng đầu ra có và không nullglobbắt đầu khác nhau ở

+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval 'words[0]=${!ref}${COMP_WORDS[i]}'
++ words[0]=ls
+ line=' '

(làm việc) vs.

+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval
+ line=' '

với nullglob. Thấy evaldòng đó không? Đó là một dấu hiệu cho thấy đối số trông giống như một mô hình toàn cầu. Mã tương ứng nằm trong __reassemble_comp_words_by_refhàm:

                # Append word separator to current or new word
                ref="$2[$j]"
                eval $2[$j]=\${!ref}\${COMP_WORDS[i]}

[là một ký tự đại diện, $2[$j]=\${!ref}\${COMP_WORDS[i]}một mẫu ký tự đại diện cũng vậy, và với nullglobnó, nó đã bị loại vì nó không khớp với gì. Điều này cũng sẽ phá vỡ ngay cả nullglobkhi thư mục hiện tại chứa một tệp có tên words0=${!ref}${COMP_WORDSi}- điều đó khá kỳ lạ, nhưng nó có thể xảy ra.

Cách khắc phục là thêm dấu ngoặc kép bị thiếu:

                eval "$2[$j]=\${!ref}\${COMP_WORDS[i]}"

Có lẽ có những phần khác của kịch bản cần sửa chữa tương tự, tôi đã không điều tra thêm.

Đây là một lỗi trong bash_completion (không phải trong chính bash). Nó đã được báo cáo vào năm 2012 và sửa nó nằm trong lộ trình cho phiên bản 3.0.


Cảm ơn, Gilles! Bạn có nghĩa là shopt -s nullglobvô hiệu hóa tự động hoàn thành tên tệp bằng tab là một lỗi trong bash_completion và đã được sửa trong bash 3.0? Tôi vẫn gặp sự cố trong bash 4.3
Tim

@Tim Đó là trong bash_completion, không phải trong bash. Phiên bản của bash không liên quan. Bạn cần (để chờ) bash_completion 3.0.
Gilles 'SO- ngừng trở nên xấu xa'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.