如何让 Emacs 使用我的 .bashrc 文件?

Posted

技术标签:

【中文标题】如何让 Emacs 使用我的 .bashrc 文件?【英文标题】:How to make Emacs use my .bashrc file? 【发布时间】:2011-09-18 15:52:05 【问题描述】:

我需要在 Emacs 中使用我的 $PATH 来运行一些命令。如何让 Emacs 使用它?我从 Ubuntu 存储库安装了 Emacs。

【问题讨论】:

***.com/questions/1393400/… This answer 似乎是一个完美的分辨率。 The DotFiles article 涵盖了 bash 点文件加载的细节,并提供了背景上下文,以便更好地理解此 QA 线程中讨论的过程。 【参考方案1】:

有许多 Emacs 软件包会更新 $PATH 环境变量和“执行路径”。这是因为 Emacs 不假定 BASH 相关文件中的定义,例如 '~/.bashrc'。

您需要在任何不从终端 shell 执行的程序中具有的所有定义,必须移至“~/.profile”,这些定义在系统启动时加载。

一些旧系统需要手动从“/etc/profile”加载用户配置文件。

【讨论】:

【参考方案2】:

这里有一个技巧I use 以确保我的 GUI Emacs 总是看到我在 shell 中看到的 $PATH

(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))

具体来说,在 OS X 上,图形 Emacs 不会获取用户的 shell 对 $PATH 的定义,所以这个技巧在那个平台上对我有帮助。

更新:此代码现已作为名为 exec-path-from-shell 的 elisp 库发布,可安装包可在 MELPA 中找到。

【讨论】:

这修复了 ubuntu 13.04 中的相同问题(我使用了包管理器安装) 好像没有使用别名。不会因为名字而指望它。有什么东西可以获取普通 bash 的别名吗? Emacs 永远不会使用您的 bash 别名,抱歉:这些仅在 bash 会话中可用。此代码和 exec-path-from-shell 包仅允许 Emacs 可靠地定位在 bash 会话中可见的相同可执行文件和脚本。 没有 bash 功能?还是我做错了什么? @Welgriv 不,函数像 bash 别名一样工作,所以我上面的评论也适用于它们。【参考方案3】:

https://***.com/a/12229404/1190077 给出了更通用的解决方案(设置所有变量和别名,而不仅仅是PATH)——关键是设置:

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

覆盖默认的"-c"(执行以下命令)。添加 "-i" 会强制 bash shell 进入交互模式,从而导致 ~/.bashrc 的来源。

【讨论】:

似乎比公认的答案更好,因为它允许使用 bash 函数。 在 MacOS 上,通过此设置,我将所有内容保留在 ~/.bash_profile,然后将行 source ~/.bash_profile 添加到 ~/.bashrc。就这么简单。最后,我的$PATH 和方便的别名可以在EmacsM-x shell-command 顺利使用。【参考方案4】:

我想出了类似的东西来采购我的 .bash_profile。如果您只关心 PATH,那么上面的其他答案之一会更简单。

它的工作原理是执行source ~/.bash_profile ; echo post-env; env,然后丢弃“post-env”之前的所有内容,然后解析“env”命令打印的“key=value”格式的值。

它可能无法完美处理所有情况,但对我来说足够好。

;;-------------------------------------------------------
;; 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
;;-------------------------------------------------------

【讨论】:

【参考方案5】:

您可以将路径设置添加到/etc/profile.d,例如

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

在 Ubuntu 中,我记得所有会话都源自您的 ~/.xsessionrc,因此您也可以在此文件中为 GUI 应用程序设置路径。

【讨论】:

【参考方案6】:

如果您的环境变量没有被拾取,可能是由于 emacs 的启动方式。检查菜单项或其他内容,然后尝试将emacs 更改为bash -c emacs

【讨论】:

【参考方案7】:

如果$PATH设置在你启动emacs的终端,你可以通过M-! <your command> RET命令执行系统命令。

【讨论】:

以上是关于如何让 Emacs 使用我的 .bashrc 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Emacs Python 模式为缩进生成 TAB?

当磁盘上的文件发生更改时,如何让 Emacs 自动刷新所有缓冲区?

如何找到已加载的 .emacs 文件?

如何让 CRON 调用正确的路径

Emacs服务器模式以及emacsclient配置

emacs建议恢复文件,但我错过了:如何让它提示?