exec-path และ $ PATH


28

ฉันได้เห็นตัวอย่างออนไลน์ที่ผู้คนเพิ่มเส้นทางไปยังเส้นทางเริ่มต้นใน Emacs ด้วย:

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

ฉันใหม่สำหรับ Elisp และฉันคิดว่าฉันเข้าใจว่าข้อความข้างต้นทำอะไร แต่ฉันมีคำถามสองสามข้อ:

  • ในสิ่งที่สั่งซื้อไม่ค้นหา Emacs ผ่านเส้นทางการดำเนินการหรือไม่ ตัวอย่างเช่นพิจารณาถึงค่าของ$PATH(env. variable) เลย (และถ้าเป็นเช่นนั้นก่อนหรือหลังexec-path?)

  • ฉันจะย่อหน้าเส้นทางดังกล่าวหลาย ฉันสามารถต่อพวกเขาต่อกันได้ไหม? เช่น

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

    หรือฉันควรทำ:

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

ฉันยังพบแพคเกจที่น่าสนใจนี้บน GitHub: exec เส้นทางจากเปลือก ทำไมจึงจำเป็นต้องมีแพ็คเกจสำหรับ?

แรงจูงใจ

เคยพบว่าคำสั่งทำงานในเชลล์ของคุณ แต่ไม่ใช่ใน Emacs?

สิ่งนี้เกิดขึ้นมากมายใน OS X ซึ่งอินสแตนซ์ Emacs เริ่มต้นจาก GUI สืบทอดชุดตัวแปรสภาพแวดล้อมเริ่มต้น

ไลบรารีนี้ใช้งานได้เพื่อแก้ไขปัญหานี้โดยการคัดลอกตัวแปรสภาพแวดล้อมที่สำคัญจากเชลล์ของผู้ใช้: มันทำงานโดยขอให้เชลล์ของคุณพิมพ์ตัวแปรที่สนใจแล้วคัดลอกลงในสภาพแวดล้อมของ Emacs


3
ยินดีต้อนรับสู่ Emacs และ Elisp! ฉันยังคงสดใหม่กับหัวข้อตัวเองและไม่ทราบคำตอบสำหรับคำถามของคุณ แต่ฉันคิดว่าฉันพูดถึงบางสิ่งที่ทำให้ชีวิตง่ายขึ้นมาก: ฟังก์ชั่นอธิบาย เช่น(describe-function 'add-to-list)( C-h f) จะให้เอกสารแก่คุณสำหรับadd-to-listฟังก์ชั่นรวมถึงลิงก์ไปยังแหล่งข้อมูล นอกจากนี้ยังมี(describe-variable 'exec-path)( C-h v) สิ่งนี้ไม่ได้หมายถึงการแสดงความคิดเห็น RTFM เอกสารเหล่านี้ไม่ตอบคำถามทั้งหมดที่คุณระบุไว้สิ่งที่มีประโยชน์
jtmoulia

ขอบคุณ @jtmoulia! ฉันจะจำไว้เสมอว่าสำหรับคำถามในอนาคต
Amelio Vazquez-Reina

นอกจากนี้ให้C-h v exec-pathใช้คู่มือ (Emacs และ Elisp) ในคู่มือi exec-pathนำคุณไปสู่คำอธิบายที่เป็นประโยชน์ ถาม Emacs ก่อน - คุณจะไม่เสียใจที่คุณทำ
ดึง

คำตอบ:


23

1) PATHและexec-path

Emacs ตั้งexec-pathจากค่าของPATHเมื่อเริ่มต้น แต่จะไม่ดูอีกครั้งในภายหลัง แต่ถ้าคุณเรียกใช้คำสั่งคำสั่งนั้นจะสืบทอดPATHไม่ใช่exec-pathเพื่อให้กระบวนการย่อยสามารถค้นหาคำสั่งที่แตกต่างจาก Emacs

ขณะที่ฟรานเชสกล่าวว่านี้สามารถโดยเฉพาะอย่างยิ่งสับสนสำหรับshell-commandเป็นที่ไม่ทำงานกระบวนการโดยตรง แต่เรียกเปลือกเพื่อให้ทำงานได้ซึ่งจะใช้ไม่ได้PATHexec-path

2) การเพิ่มหลายเส้นทางไปยัง exec-path

เพียงโทรadd-to-listซ้ำ ๆ :

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

โปรดทราบว่าadd-to-listเพิ่มในตอนต้นของรายการดังนั้นสิ่งนี้จะจบลงด้วย"PATH2"การอยู่ในexec-pathก่อนหน้า"PATH1"นี้

คุณยังสามารถใช้การเข้าถึงรายการ "ระดับต่ำ" เพิ่มเติม:

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

นี้จะเพิ่ม"PATH1"และ"PATH2"ที่คุณexec-pathในลำดับที่

3) PATH ของ Mac OS

ปัญหาบน Mac OS X คือ Mac OS ไม่ได้ตั้งค่าสภาพแวดล้อมแบบเดียวกันเมื่อคุณเรียกโปรแกรมจาก UI สากลหรือเมื่อคุณเรียกจากเชลล์ ซึ่งหมายความว่าการเรียกใช้ Emacs จากเชลล์จะส่งผลให้ตัวแปรสภาพแวดล้อมที่แตกต่างกันถูกตั้งค่ามากกว่าเมื่อคุณเรียกใช้จาก Finder สิ่งนี้น่ารำคาญเป็นพิเศษหากคุณตั้งค่าตัวแปรสภาพแวดล้อมใน.bashrcหรือคล้ายกันเนื่องจากจะไม่มีผลต่อ Emac "ระดับโลก"

แพคเกจเริ่มเปลือกและนำเข้าตัวแปรสภาพแวดล้อมจากที่นั่นเลียนแบบสภาพแวดล้อมที่คุณได้รับจากเปลือกใน Emacs เริ่มต้นทั่วโลก


ขอบคุณ Jorgen เกี่ยวกับไตรมาสที่ 3: คุณรู้หรือไม่ว่าPATHมีการกำหนดค่าเริ่มต้นสำหรับโปรแกรมที่เริ่มต้นจาก UI ทั่วโลก (สภาพแวดล้อมเดสก์ท็อป) หรือไม่ ฉันมีปัญหาเดียวกันกับPYTHONPATHในelpy:) เมื่อฉันเริ่ม Emacs จากเดสก์ท็อป Emacs ไม่ทราบPYTHONPATHคำจำกัดความของฉันใน.zshenvไฟล์ของฉัน(ไฟล์ init สำหรับzsh) ซึ่งน่าผิดหวังมากเนื่องจากelpyไม่รู้ว่าจะหาแพ็คเกจ Python ของฉันได้ที่ไหน ฉันมีความสุขที่จะย้ายPYTHONPATHคำจำกัดความเหล่านี้ไปยังinitไฟล์เชลล์ที่แตกต่างกัน(แม้ว่าจะเป็นการดีที่ฉันต้องการให้ Emacs ใช้คำจำกัดความจากฉัน.zshenv)
Amelio Vazquez-Reina

ฉันเกรงว่าฉันไม่รู้มากเกี่ยวกับ Mac OS X Google ได้อย่างรวดเร็วมาให้ฉัน stackoverflow.com/questions/135688/ซึ่งดูเหมือนว่าจะบ่งบอกว่า launchd.conf เป็นสถานที่ที่เหมาะสม หากสิ่งที่คุณต้องการนี้เป็น Emacs คุณสามารถของหลักสูตรเพียงแค่ตั้งทั้งสองexec-pathและในของคุณPATH .emacsคุณสามารถตั้งค่าการใช้PATH (setenv "PATH" (format "%s:%s" "/new/path/element" (getenv "PATH")))
Jorgen Schäfer

ขอบคุณ ฉันรู้ว่า Q ต่อไปนี้เบี่ยงเบนไปเล็กน้อยจาก OP แต่มีวิธีใดที่จะระบุใน Emacs PYTHONPATHที่elpyควรใช้?
Amelio Vazquez-Reina

คุณสามารถปรับเปลี่ยนสำหรับตัวอย่างการใช้process-environment setenvคุณสามารถทำสิ่งนั้นได้elpy-mode-hookแต่มันเป็นตัวแปร globsl และการทำให้บัฟเฟอร์ในเครื่องสามารถนำไปสู่พฤติกรรมที่สับสนได้ง่าย
Jorgen Schäfer

9

เมื่อ emacs เริ่มต้นกระบวนการภายนอกใหม่โดยใช้ฟังก์ชั่นดั้งเดิมเช่นcall-processหรือstart-processไฟล์ปฏิบัติการจะถูกค้นหาในexec-path(และไม่$PATH)

อย่างไรก็ตามฟังก์ชั่นเช่นshell-commandเริ่มต้นเชลล์เป็นกระบวนการย่อยและส่งผ่านคำสั่งที่คุณต้องการเรียกใช้ เพื่อรันคำสั่งนี้เชลล์จะพยายามค้นหาไฟล์เรียกทำงานใน$PATH(และไม่ใช่exec-path)

ดังนั้นexec-pathสิ่งที่สำคัญที่สุดสำหรับกระบวนการภายนอกซึ่งเริ่มต้นโดย emacs เองในขณะ$PATHที่สิ่งที่นับสำหรับคำสั่งที่คุณเรียกใช้ตัวคุณเองด้วยฟังก์ชั่นระดับสูง (ใช้M-!ตัวอย่าง)


หากคุณต้องการเพิ่มหลายไดเรกทอรีexec-pathคุณควรใช้ add-to-listหลายครั้ง

คุณสามารถทำได้ด้วยตนเอง

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

หรือใช้วง

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

สำหรับคำถามที่สามของคุณหาก emacs ถูกเปิดตัวจากสภาพแวดล้อมเดสก์ท็อปมันจะสืบทอดสภาพแวดล้อมจากมันซึ่งอาจจะไม่สมบูรณ์กว่าเชลล์เต็ม

นี่หมายความว่าบางครั้งอาจจำเป็นต้องทำให้ Emacs สมบูรณ์เพื่อ$PATHใช้ในสิ่งที่เปลือกหอยปกติเห็น นี่คือจุดประสงค์ของexec-path-from-shellห้องสมุดที่คุณพูดถึง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.