2011-06-20 68 views
11

Tôi cần sử dụng $PATH trong Emacs để chạy một số lệnh. Làm thế nào tôi có thể làm cho Emacs sử dụng nó? Tôi đã cài đặt Emacs từ kho lưu trữ Ubuntu.Làm thế nào để làm cho Emacs sử dụng tệp .bashrc của tôi?

+0

http://stackoverflow.com/questions/1393400/commands-from-bashrc-not-available-in-emacs –

+0

[Câu trả lời này] (https://emacs.stackexchange.com/a/29120/8849) dường như là một giải pháp hoàn hảo. –

Trả lời

29

Dưới đây là một thủ thuật I use để đảm bảo GUI Emacs của tôi luôn luôn nhìn thấy cùng $PATH mà tôi nhận được bên trong một vỏ:

(defun set-exec-path-from-shell-PATH() 
    (let ((path-from-shell (replace-regexp-in-string 
          "[ \t\n]*$" 
          "" 
          (shell-command-to-string "$SHELL --login -i -c 'echo $PATH'")))) 
    (setenv "PATH" path-from-shell) 
    (setq eshell-path-env path-from-shell) ; for eshell users 
    (setq exec-path (split-string path-from-shell path-separator)))) 

(when window-system (set-exec-path-from-shell-PATH)) 

Cụ thể, trên OS X, một Emacs đồ họa sẽ không lấy nét vỏ của của người sử dụng $PATH, vì vậy mẹo này giúp tôi trên nền tảng đó.

Cập nhật: mã này hiện đã được xuất bản dưới dạng thư viện elisp có tên là exec-path-from-shell và các gói có thể cài đặt có sẵn trong MELPA.

+0

Điều này khắc phục sự cố tương tự trong ubuntu 13.04 (Tôi đã sử dụng cài đặt trình quản lý gói) – Anake

+0

Có vẻ như không sử dụng bí danh. Sẽ không mong đợi nó từ vì tên mặc dù. Có điều gì đó để nhận được bí danh của bash bình thường không? – Zelphir

+0

Emacs sẽ không bao giờ sử dụng bí danh bash của bạn, xin lỗi: những người chỉ có sẵn trong các phiên bash. Mã này và gói exec-path-from-shell chỉ cho phép Emacs xác định vị trí một cách đáng tin cậy các tệp và tập lệnh thực thi giống nhau có thể nhìn thấy trong các phiên bash của bạn. – sanityinc

0

Nếu $PATH được đặt trong thiết bị đầu cuối bạn khởi chạy các emacs, bạn có thể thực thi lệnh hệ thống thông qua lệnh M-! <your command> RET.

1

Nếu env vars của bạn không được chọn, nó có thể là do cách bắt đầu emacs. Kiểm tra menuitem hoặc bất cứ điều gì và thử thay đổi emacs thành bash -c emacs.

1

Bạn có thể thêm các thiết lập đường dẫn đến /etc/profile.d như

# /etc/profile.d/path.sh 
export PATH="$PATH:/usr/local" 

Trong Ubuntu, tôi nhớ tất cả các phiên nguồn ~/.xsessionrc của bạn, vì vậy bạn cũng có thể đặt đường dẫn trong tập tin này cho các ứng dụng GUI.

1

Tôi đã đưa ra một cái gì đó tương tự để tìm nguồn cung ứng .bash_profile của tôi. Nếu bạn chỉ quan tâm đến PATH, một trong những câu trả lời khác ở trên là đơn giản hơn.

Nó hoạt động bằng cách thực hiện source ~/.bash_profile ; echo post-env; env rồi vứt bỏ mọi thứ trước "post-env", sau đó phân tích cú pháp các giá trị theo định dạng "key = value" mà lệnh "env" in.

Nó có thể không xử lý mọi trường hợp một cách hoàn hảo, nhưng hoạt động tốt đủ cho tôi.

;;------------------------------------------------------- 
;; begin sourcing of .bash_profile 

;; only do this on Mac OS X 
(when (string= system-type "darwin") 
    ;; require common lisp extensions, for search 
    (require 'cl) 


    (defun src-shell-unescape (string) 
    ;; replace \n \t \r \b \a \v \\ 
    ;; and octal escapes of the form \0nn 

    (replace-regexp-in-string 
    "\\\\\\([ntrbav]\\|\\(\\\\\\)\\|\\(0[0-7][0-7]\\)\\)" 
    (lambda (str) 
     ;; interpret octal expressions 
     ;; of the form "\0nn" 
     (let ((char1 (aref str 1))) 
    (cond ((= ?0 (aref str 1)) 
     (byte-to-string 
     (+ (* (- (aref str 2) ?0) 8) 
      (- (aref str 3) ?0)))) 
      ((eq char1 ?n) "\n") 
      ((eq char1 ?t) "\t") 
      ((eq char1 ?r) "\r") 
      ((eq char1 ?b) "\b") 
      ((eq char1 ?a) "\a") 
      ((eq char1 ?v) "\v") 
      ((eq char1 ?\\) "\\\\") 
      (t "")))) string)) 

    (defun src-set-environment-from-env-output(env-output) 
    ;; set the environment from shell's "env" output 
    (let ((lines (split-string env-output "\n" t))) 
     (dolist (line lines) 
    (let ((idx-equals (search "=" line))) 
     (when (and (not (eq idx-equals nil)) 
      (> idx-equals 1)) 
     (let ((key (substring line 0 idx-equals)) 
      (value (substring line (+ idx-equals 1)))) 
      (setenv key (src-shell-unescape value)) 
      ;; (message "%s = %s" key value) 
     )))))) 

    (defun src-source-shell-file (file-name) 
    ;; if your shell is sh rather than bash, the "source " may need 
    ;; to be ". " instead 
    (let* ((command (concat "source '" file-name "'; echo 'post-env'; env")) 
     (output (shell-command-to-string command)) 
     (idx-post-env (search "post-env" output))) 
     (if (eq nil idx-post-env) 
     (message "Didn't find expected output after sourcing %s. Found: %s" file-name output) 
    (let ((trimmed-output (substring output idx-post-env))) 
     ;; (message "trimmed-output: %s" trimmed-output) 
     (src-set-environment-from-env-output trimmed-output))))) 



    (src-source-shell-file (expand-file-name "~/.bash_profile"))) 


;; end sourcing of .bash_profile 
;;------------------------------------------------------- 
1

Một giải pháp tổng quát hơn (để thiết lập tất cả các biến và bí danh, không chỉ PATH) được đưa ra trong https://stackoverflow.com/a/12229404/1190077 - chìa khóa là để thiết lập:

(setq shell-command-switch "-ic") 

đó sẽ ghi đè mặc định "-c" (thực hiện lệnh sau). Việc thêm "-i" buộc vỏ bash vào chế độ tương tác, dẫn đến việc tìm nguồn cung ứng ~/.bashrc.

Các vấn đề liên quan