đường dẫn và $ PATH


28

Tôi đã thấy các ví dụ trực tuyến nơi mọi người thêm đường dẫn vào đường dẫn mặc định trong Emacs với:

(add-to-list 'exec-path "/usr/local/bin/")

Tôi chưa quen với Elisp và tôi nghĩ tôi hiểu những gì tuyên bố trên, nhưng tôi có một vài câu hỏi:

  • Theo thứ tự nào Emacs tìm kiếm thông qua các đường dẫn thực hiện? Ví dụ, nó có xem xét giá trị của $PATH(biến env.) (Và nếu vậy, trước hay sau exec-path?)

  • Làm thế nào tôi có thể thêm trước nhiều đường dẫn như vậy? Tôi chỉ có thể tiếp tục nối chúng? ví dụ

    (add-to-list 'exec-path "PATH1", "PATH2")
    

    hoặc tôi nên làm:

    (add-to-list 'exec-path "PATH1:PATH2:PATH3") 
    

Tôi cũng tìm thấy gói thú vị này trên GitHub: exec-path-from-shell . Tại sao cần một gói cho việc này?

Động lực

Bạn đã bao giờ thấy rằng một lệnh hoạt động trong shell của bạn, nhưng không phải trong Emacs?

Điều này xảy ra rất nhiều trên OS X, trong đó một phiên bản Emacs bắt đầu từ GUI kế thừa một bộ biến môi trường mặc định.

Thư viện này hoạt động giải quyết vấn đề này bằng cách sao chép các biến môi trường quan trọng từ trình bao của người dùng: nó hoạt động bằng cách yêu cầu trình bao của bạn in ra các biến quan tâm, sau đó sao chép chúng vào môi trường Emacs.


3
Chào mừng đến với Emacs và Elisp! Bản thân tôi vẫn còn khá mới mẻ với chủ đề này và không biết câu trả lời cho câu hỏi của bạn, nhưng tôi nghĩ tôi đã đề cập đến một thứ khiến cuộc sống trở nên dễ dàng hơn rất nhiều: các chức năng mô tả. ví dụ (describe-function 'add-to-list)( C-h f) sẽ cung cấp cho bạn tài liệu cho add-to-listhàm, cũng như các liên kết đến nguồn. Cũng có (describe-variable 'exec-path)( C-h v). Đây không phải là một nhận xét RTFM - những tài liệu này không trả lời tất cả các câu hỏi bạn liệt kê, chỉ là một cái gì đó hữu ích.
jtmoulia

Cảm ơn @jtmoulia! Tôi chắc chắn sẽ ghi nhớ điều đó cho các câu hỏi trong tương lai.
Amelio Vazquez-Reina

Ngoài ra C-h v exec-path, hãy sử dụng (các) hướng dẫn sử dụng (Emacs và Elisp). Trong một hướng dẫn, i exec-pathhướng dẫn bạn đến một lời giải thích hữu ích. Hỏi Emacs trước - bạn sẽ không xin lỗi bạn đã làm.
vẽ

Câu trả lời:


23

1) PATHexec-path

Emacs được đặt exec-pathtừ giá trị PATHkhi khởi động, nhưng sẽ không xem xét lại sau. Nhưng nếu bạn chạy một lệnh, nó sẽ thừa hưởng PATH, chứ không phải exec-path, vì vậy quy trình con có thể tìm thấy lệnh khác so với Emacs không.

Như Francesco nói, điều này có thể đặc biệt khó hiểu shell-command, vì nó không chạy trực tiếp một quy trình, nhưng gọi một trình bao để chạy nó, sẽ sử dụng PATH, không sử dụng exec-path.

2) Thêm nhiều đường dẫn đến exec-path

Chỉ cần gọi add-to-listliên tục:

(add-to-list 'exec-path "PATH1")
(add-to-list 'exec-path "PATH2")

Hãy lưu ý rằng add-to-listthêm vào đầu danh sách, vì vậy điều này sẽ kết thúc với "PATH2"việc ở exec-pathtrước "PATH1".

Bạn cũng có thể sử dụng nhiều quyền truy cập "cấp thấp" hơn vào danh sách:

(setq exec-path (append '("PATH1" "PATH2")
                        exec-path))

Điều này sẽ thêm "PATH1""PATH2"vào của bạn exec-path, theo thứ tự đó.

3) Mac OS 'PATH

Vấn đề trên Mac OS X là Mac OS không đặt môi trường giống nhau khi bạn gọi một chương trình từ UI toàn cầu hoặc khi bạn gọi nó từ shell. Điều này có nghĩa là việc chạy Emacs từ shell sẽ dẫn đến các biến môi trường khác nhau được đặt so với khi bạn chạy nó từ công cụ tìm. Điều này đặc biệt khó chịu nếu bạn đặt các biến môi trường trong .bashrchoặc tương tự, vì điều đó sẽ không ảnh hưởng đến các Emacs "toàn cầu".

Gói dường như bắt đầu một shell và nhập các biến môi trường từ đó, mô phỏng môi trường bạn nhận được từ shell trong Emacs khởi động toàn cầu.


Cảm ơn Jorgen. Về Q3: Bạn có biết nơi PATHđược xác định mặc định cho các chương trình bắt đầu từ UI toàn cầu (môi trường máy tính để bàn) không? Tôi đang có cùng một vấn đề với PYTHONPATHtrong elpy:). Khi tôi khởi động Emacs từ máy tính để bàn, Emacs không biết các PYTHONPATHđịnh nghĩa của tôi trong .zshenvtệp của tôi (một tệp init zsh), điều này rất bực bội, vì elpykhông biết tìm gói Python của tôi ở đâu. Tôi rất vui khi chuyển các PYTHONPATHđịnh nghĩa này sang một inittệp shell khác (mặc dù lý tưởng nhất là tôi muốn Emacs sử dụng các định nghĩa từ tôi .zshenv)
Amelio Vazquez-Reina

Tôi e rằng tôi hoàn toàn không biết nhiều về Mac OS X. Một google nhanh chóng đưa tôi đến stackoverflow.com/questions/135688/ trên đó dường như chỉ ra rằng launchd.conf là đúng nơi. Nếu tất cả những gì bạn cần là Emacs, tất nhiên bạn có thể chỉ cần đặt cả hai exec-pathPATHtrong của bạn .emacs. Bạn có thể thiết lập PATHbằng cách sử dụng (setenv "PATH" (format "%s:%s" "/new/path/element" (getenv "PATH"))).
Jorgen Schäfer

Cảm ơn. Tôi biết những điều sau Q phân kỳ một chút từ OP, nhưng là có cách nào để xác định trong Emacs sự PYTHONPATHrằng elpynên sử dụng?
Amelio Vazquez-Reina

Bạn có thể sửa đổi process-environment, ví dụ bằng cách sử dụng setenv. Bạn có thể làm điều đó trong elpy-mode-hook, nhưng nó là một biến số globsl và làm cho nó trở thành bộ đệm cục bộ có thể dễ dàng dẫn đến hành vi khó hiểu.
Jorgen Schäfer

9

Khi emacs bắt đầu một quy trình bên ngoài mới bằng cách sử dụng các hàm nguyên thủy như call-processhoặc start-process, tệp thực thi được tìm kiếm trong exec-path(và không $PATH)

Tuy nhiên, một chức năng như shell-commandkhởi động hệ vỏ như một quy trình con và truyền cho nó lệnh bạn muốn chạy. Để thực thi lệnh này, shell sẽ cố gắng tìm tệp thực thi trong $PATH(chứ không phải trong exec-path).

Do đó, exec-pathlà thứ được tính nhiều nhất cho các quy trình bên ngoài được khởi động bởi chính emacs, trong khi đó $PATHlà thứ được tính cho các lệnh bạn tự chạy với chức năng cấp cao hơn ( M-!ví dụ sử dụng )


Nếu bạn muốn thêm nhiều thư mục vào exec-path, bạn nên sử dụng add-to-listnhiều lần.

Bạn có thể làm bằng tay

(add-to-list 'exec-path "dir1")
(add-to-list 'exec-path "dir2")

hoặc sử dụng một vòng lặp

(dolist (dir '("dir1" "dir2"))
  (add-to-list 'exec-path dir))

Về câu hỏi thứ ba của bạn, nếu emacs được khởi chạy từ môi trường máy tính để bàn, nó sẽ thừa hưởng môi trường từ nó, có thể chưa hoàn thiện hơn so với vỏ hoàn chỉnh.

Điều này có nghĩa là đôi khi có thể cần phải hoàn thành giá trị của Emacs để $PATHsử dụng những gì một vỏ thông thường nhìn thấy. Đây là mục đích của exec-path-from-shellthư viện mà bạn đề cập.

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.