環境変数を再読み込み


10

この質問はスーパーユーザーis-there-to-reload-environment-variables-in-emacsで行われましたが、適切な解決策はありませんでした。

EmacsClientを使用していて、30を超えるバッファが開いていることがよくあります。シェルで環境変数を変更した場合は、EmacsClientを終了して(すべてのバッファを再度開く)、Emacsでも環境変数を手動で設定する必要があります。Emacsで環境変数を簡単に更新できないのは不愉快です。助言がありますか?


親プロセスで環境変数を変更しても、子にエクスポートされた値は更新されないため、これを行う簡単な方法はありません。
Erik Hetzner、2015年

回答:


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するために新しいシェルを生成することに注意してください。したがって、シェル構成ファイル(など.bashrc)で設定した変数に対してのみ機能しますが、を使用して実行中のシェルセッションでのみ設定した変数には機能しませんexport。これらの変数を抽出することは、/proc/プロセスを実行するためのAPIまたは同様のAPIを検査する複雑なハックなしでは一般に不可能です。


後者/一時的な値については、Emacsがサーバーとして実行されている場合、更新された値をそのシェルから直接emacsclientに渡すのは簡単です。
フィル、2015年

@philsありがとう、私の最新の回答を参照してください。
HåkonHægland15年

5

回避策として、以下を使用できます(Linux、Bash)。

  • 最初にprintenv -0 > env.txtBashターミナルウィンドウから実行します。
  • 次に、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コマンドのオプションを使用してよりエレガントに実行できることがわかりますupdate_emacs_env:Bashスクリプトを定義します:

#! /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、シェルコマンドラインから入力するだけで、Emacs環境変数を更新できます。


また、関数内から "printenv"を実行することもできます...
mankoff

@mankoff実は、私はあなたが...いないと思う:)(それは、古い値を印刷します)
ホーコンHægland

ログインフラグを使用してシェルを生成できませんか?またはsource.bashrc、.bash_profileなど?
マンコフ2015年

はい..しかし、それだろう特殊なケースのためではない助け、私は使用して、コマンドラインから直接シェルにエクスポートする場合export VAR=value
ホーコンHægland

はい、そのようなことは考えていませんでした。クライアントとのエレガントなソリューション!
マンコフ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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.