重新加载环境变量


10

超级用户是否有在emacs中重新加载环境变量的方法提出了此问题,但是没有给出好的解决方案。

我使用EmacsClient时通常会打开30多个缓冲区,如果我在外壳中更改环境变量,则需要退出EmacsClient(然后重新打开所有缓冲区),或者也必须在Emacs中手动设置环境变量。我无法在Emacs中轻松更新环境变量,这很烦人。有什么建议么?


没有直接的方法可以执行此操作,因为在父进程中更改环境变量不会像导出到子进程那样更新其值。
Erik Hetzner 2015年

Answers:


7

exec-path-from-shell提供了该exec-path-from-shell-copy-env命令,该命令可让您将环境变量的值复制到Emacs会话。例如,还要在Emacs中M-x exec-path-from-shell-copy-env RET FOO设置的值$FOO

请注意,将exec-path-from-shell-copy-env生成一个新的 shell来提取环境变量的值。因此,它仅适用于您在shell配置文件(例如.bashrc)中设置的变量,而不适用于仅在正在运行的Shell会话中使用设置的变量export。如果没有繁琐的检查程序/proc/或运行过程的类似API,通常就不可能提取这些变量。


关于后一个/瞬态值,如果Emacs作为服务器运行,那么将更新后的值直接从该Shell传递到emacsclient会很容易。
菲尔斯,2015年

@phils谢谢,请参阅我的最新答案。
HåkonHægland2015年

5

解决方法是,可以使用以下命令(Linux,Bash):

  • 首先printenv -0 > env.txt从Bash终端窗口运行
  • 然后从Emacs内部运行
(defun my-update-env ()
  (interactive)
  (let ((str 
         (with-temp-buffer
           (insert-file-contents "env.txt")
           (buffer-string))) lst)
    (setq lst (split-string str "\000"))
    (while lst
      (setq cur (car lst))
      (when (string-match "^\\(.*?\\)=\\(.*\\)" cur)
        (setq var (match-string 1 cur))
        (setq value (match-string 2 cur))
        (setenv var value))
      (setq lst (cdr lst)))))

更新资料

事实证明,使用--eval以下emacsclient命令的选项可以更优雅地完成此操作:定义Bash脚本update_emacs_env

#! /bin/bash

fn=tempfile
printenv -0 > "$fn" 
emacsclient -s server_name -e '(my-update-env "'"$fn"'")' >/dev/null

server_name您的Emacs服务器名称在哪里,并且my-update-env是由~/.emacs文件定义的函数:

(defun my-update-env (fn)
  (let ((str 
         (with-temp-buffer
           (insert-file-contents fn)
           (buffer-string))) lst)
    (setq lst (split-string str "\000"))
    (while lst
      (setq cur (car lst))
      (when (string-match "^\\(.*?\\)=\\(.*\\)" cur)
        (setq var (match-string 1 cur))
        (setq value (match-string 2 cur))
        (setenv var value))
      (setq lst (cdr lst)))))

现在,您只需update_emacs_env在shell命令行中键入以更新Emacs环境变量。


您也可以从函数内部运行“ printenv” ...
mankoff 2015年

@mankoff其实我觉得你不能.. :)(这将打印旧的值即可)
哈康Hægland

您不能生成带有登录标志的shell吗?还是source.bashrc,.bash_profile等?
mankoff 2015年

是的..但它会为特殊情况不能帮助,如果我直接在命令行外壳出口,使用export VAR=value
哈康Hægland

是的,我没有想到这种情况。与客户的优雅解决方案!
mankoff 2015年

3

我曾经用这个:

function export-emacs {
    if [ "$(emacsclient -e t)" != 't' ]; then
        return 1
    fi

    for name in "${@}"; do
        value=$(eval echo \"\$${name}\")
        emacsclient -e "(setenv \"${name}\" \"${value}\")" >/dev/null
    done
}

让您导出命名变量EG:

export EDITOR=vim
export-emacs EDITOR
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.