tra-loi-cau-hoi-phat-trien-web.com

Dừng mở rộng ký tự đại diện Shell?

Có cách nào để một chương trình dòng lệnh được biên dịch nói với bash hoặc csh rằng nó không muốn bất kỳ ký tự đại diện nào trong các tham số của nó được mở rộng không?

Chẳng hạn, người ta có thể muốn một lệnh Shell như:

foo *

chỉ đơn giản trả về giá trị số ASCII của ký tự đó.

60
hotpaw2

Không. Việc mở rộng diễn ra trước khi lệnh thực sự được chạy.
Bạn chỉ có thể vô hiệu hóa quả cầu trước khi chạy lệnh hoặc bằng cách trích dẫn ngôi sao.

$ # quote it
$ foo '*'

$ # or escape it
$ foo \*

$ # or disable the glob (noglob)
$ set -f
$ foo *
86
c00kiemon5ter

Mặc dù đúng là bản thân một lệnh không thể tắt tính năng toàn cầu, nhưng người dùng có thể nói với Unix Shell không được toàn cầu hóa một lệnh cụ thể. Điều này thường được thực hiện bằng cách chỉnh sửa các tệp cấu hình của Shell. Giả sử lệnh foo có thể được tìm thấy dọc theo đường dẫn lệnh, những điều sau đây sẽ cần được thêm vào tệp cấu hình phù hợp:

Đối với vỏ sh, bash và ksh:

alias foo='set -f;foo';foo(){ command foo "[email protected]";set +f;}

Đối với vỏ csh và tcsh:

alias foo 'set noglob;\foo \!*;unset noglob'

Đối với Shell zsh:

alias foo='noglob foo'

Đường dẫn lệnh không phải được sử dụng. Giả sử lệnh foo được lưu trong thư mục ~/bin, sau đó ở trên sẽ trở thành:

Đối với vỏ sh, bash và ksh:

alias foo='set -f;foo';foo(){ ~/bin/foo "[email protected]";set +f;}

Đối với vỏ csh và tcsh:

alias foo 'set noglob;$home/bin/foo \!*;unset noglob'

Đối với Shell zsh:

alias foo='noglob ~/bin/foo'

Tất cả những điều trên đã được kiểm tra bằng OSX 10.9.2 của Apple .. Lưu ý: Khi sao chép mã ở trên, hãy cẩn thận về việc xóa bất kỳ khoảng trắng nào. Họ có thể là đáng kể.

Cập nhật:

Người dùng geira đã chỉ ra rằng trong trường hợp bash Shell

alias foo='set -f;foo';foo(){ ~/bin/foo "[email protected]";set +f;}

có thể được thay thế bằng

reset_expansion(){ CMD="$1";shift;$CMD "[email protected]";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'

mà loại bỏ sự cần thiết cho chức năng foo.

Một số trang web được sử dụng để tạo tài liệu này:

44
David Anderson

Việc mở rộng được Shell thực hiện trước khi chương trình của bạn được chạy. Chương trình của bạn không có manh mối về việc mở rộng đã xảy ra hay chưa. 

   set -o noglob

sẽ tắt mở rộng trong Shell gọi, nhưng bạn phải làm điều đó trước bạn gọi chương trình của mình.

Thay thế là trích dẫn các đối số của bạn, ví dụ:.

foo "*"
7
Brian Agnew

Chú ý: nếu không có tên nào khớp với mặt nạ, bash sẽ vượt qua đối số như hiện tại, mà không cần mở rộng!

Bằng chứng (pa.py là một tập lệnh rất đơn giản, chỉ in các đối số của nó):

 $ ls
f1.cc  f2.cc  pa.py
 $ ./pa.py *.cc
['./pa.py', 'f1.cc', 'f2.cc']
 $ ./pa.py *.cpp
['./pa.py', '*.cpp']
1
lesnik

Không. Shell kiểu Bourne luôn thực hiện globalbing khi thích hợp trước khi thực hiện lệnh. Người dùng phải trích dẫn hoặc thoát khỏi các đối số để ngăn chặn toàn cầu, như foo \*; chương trình thực tế đang được thực thi không thể chỉ ra một ưu tiên.

0
mrb