Phần trăm trong biến môi trường $ PATH


16

$ PATH của tôi trông như thế này:

/home/torbjorr/deployed/vector/x86_64-GNU%2fLinux:/home/torbjorr/deployed/typewriter/x86_64-GNU%2fLinux:/home/torbjorr/deployed/mustudio/x86_64-GNU%2fLinux:/home/torbjorr/deployed/mathext/x86_64-GNU%2fLinux:/home/torbjorr/deployed/doxymax/x86_64-GNU%2fLinux:/home/torbjorr/deployed/c2tex/x86_64-GNU%2fLinux:/home/torbjorr/deployed/x86_64-GNU%2fLinux/wand:/home/torbjorr/deployed/x86_64-GNU%2fLinux/spellesc:/home/torbjorr/deployed/x86_64-GNU%2fLinux/projinit:/home/torbjorr/deployed/x86_64-GNU%2fLinux/herbs:/home/torbjorr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Trong bash, tôi có thể không gặp vấn đề gì khi gọi đũa phép nằm ở

/home/torbjorr/deployed/x86_64-GNU%2fLinux/wand

giống

$ wand
(i) Mål från "main.cpp" har registrerats
(i) Skapar katalog "__wand_targets_dbg"
(i) Kör g++ "main.cpp" -fpic -L"/home/torbjorr/deployed"  -g -Wall -std=c++11 -I"/home/torbjorr/deployed" -o "__wand_targets_dbg/cb-template

Tuy nhiên, trong chế độ tương thích vỏ bourne, không thể tìm thấy đũa:

$ wand
sh: 2: wand: not found

Có vẻ như vấn đề là dấu% trong các đường dẫn này. Dấu hiệu này đã được thêm bằng mã hóa URL để tên "GNU / Linux" có thể được sử dụng trong tên thư mục mặc dù đó không phải là tên tệp hợp lệ. Có thể để tên làm việc trong sh, hoặc làm cho lệnh sh hoạt động như bash. Đó là, làm cho bash hoạt động giống nhau mặc dù nó được gọi bằng lệnh / bin / sh, liên kết tượng trưng để bash nào.


Câu hỏi hay. Dường như nhân vật '%' không hoạt động chính xác trong $ PATH từ sh(nó là ok trong bashzshmặc dù). Gọi trực tiếp các công việc thực thi trong sh; rất lạ.
Rmano

Điều gì xảy ra nếu bạn sử dụng 2 %%?
mikeerv

Hoặc thoát%?
mdpc

Câu trả lời:


15

Đó không phải là vỏ Bourne, hay bashmô phỏng vỏ Bourne, đó là vỏ Almquist, trong trường hợp của bạn có lẽ là vỏ Debian Almquist (một ngã ba Linux của chính bản thân Debian của BSD dựa trên vỏ Almquist gốc).

Trong vỏ Almquist (phiên bản gốc và phiên bản hiện đại), %được sử dụng PATHcho các tính năng bổ sung cụ thể ash. Trích dẫn từ tài liệu:

Tìm kiếm đường dẫn

Khi định vị một lệnh, shell trước tiên nhìn xem nó có chức năng shell theo tên đó không. Sau đó, nếu PATH không chứa mục nhập %builtin, nó sẽ tìm lệnh dựng sẵn theo tên đó. Cuối cùng, nó lần lượt tìm kiếm từng mục trong PATH cho lệnh.

Giá trị của biến PATH phải là một chuỗi các mục được phân tách bằng dấu hai chấm. Mỗi mục bao gồm một tên thư mục hoặc một tên thư mục theo sau là một cờ bắt đầu bằng dấu phần trăm. Thư mục hiện tại phải được chỉ định bởi một tên thư mục trống. Nếu không có dấu phần trăm, thì mục nhập sẽ khiến shell tìm kiếm lệnh trong thư mục được chỉ định. Nếu cờ là %builtin danh sách các lệnh dựng sẵn shell được tìm kiếm. Nếu cờ là %func thư mục được tìm kiếm một tệp được đọc làm đầu vào cho trình bao. Tệp này sẽ xác định một hàm có tên là tên của lệnh đang được tìm kiếm.

Tên lệnh chứa dấu gạch chéo được thực hiện đơn giản mà không thực hiện bất kỳ tìm kiếm nào ở trên.

Các shell khác thích kshhoặc zshcó cơ chế tự động tải tương tự của cơ chế hàm, nhưng chúng sử dụng một biến khác ( $FPATH), nhưng bạn không thể xác định hàm nào hoặc hàm thực thi được ưu tiên.

Trong trường hợp của bạn, /home/torbjorr/deployed/vector/x86_64-GNU%2fLinuxđược hiểu là /home/torbjorr/deployed/vector/x86_64-GNUthư mục với 2fLinuxcờ. Lá cờ đó bị bỏ qua vì nó là không rõ.

Không có cách nào xung quanh đó. Ngay cả khi tro có cơ chế thoát hiểm để điều này %không được xử lý đặc biệt, thì nó sẽ không hoạt động trong các vỏ khác hoặc những thứ khác trông $PATHgiống như vậy execvp().

Bạn sẽ cần xóa các %ký tự khỏi $PATH, vì vậy hãy đổi tên thư mục của bạn hoặc thêm liên kết tượng trưng.

Hoặc không sử dụng ashcho của bạn /bin/sh. Các triển khai shell POSIX nhẹ khác không bao gồm yashmksh.


Mặc dù câu trả lời này đưa ra lời giải thích, nhưng nó không đưa ra giải pháp. Có cách nào tương thích để giữ%.
dùng877329

@ user877329, không có giải pháp thực sự ở đây. Xem chỉnh sửa của tôi.
Stéphane Chazelas

3
Nói cách khác, Debian shvi phạm tiêu chuẩn POSIX. Cho rằng điểm cần có một shchính xác là bạn nên chắc chắn không vấp phải một số tiện ích mở rộng vỏ không tương thích (tôi đoán không ai sử dụng /bin/shlàm vỏ đăng nhập ngày nay), tôi coi đó là một lỗi.
celtschk

1
@celtschk, đã đồng ý mặc dù điểm sử dụng ashcho / bin / sh là nhiều hơn để tránh bị phạt hiệu suất khi sử dụng bash, vì vậy sử dụng yashhoặc mksh(hoặc poshnếu bạn muốn loại trừ tất cả các tiện ích mở rộng) vẫn là một lựa chọn tốt hơn so với sử dụng bash. Ngoài ra, người ta có thể coi nó là một trường hợp góc. Không ai thường có %trong một thành phần đường dẫn. Hầu hết các shell đều có các trường hợp góc mà chúng không tuân thủ POSIX.
Stéphane Chazelas

1
@mtmiller, đó không phải là cách tôi đọc ý nghĩa của bộ ký tự tên tệp di động (PFCS). POSIX chỉ định API lập trình nhưng không triển khai hệ thống tệp. PFCS là bảo đảm POSIX tối thiểu sẽ hoạt động ở bất kỳ hệ thống tệp nào, bất kể miền địa phương hiện tại nhưng không có lý do gì để công cụ không chấp nhận ký tự trong tên tệp nếu được hệ thống tệp hỗ trợ và hợp lệ trong miền địa phương hiện tại. Lưu ý rằng ví dụ POSIX yêu cầu phải có [lệnh ngay cả khi ký tự đó không có trong PFCS.
Stéphane Chazelas
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.