Перезагрузить переменные среды


10

Этот вопрос задавался в superuser is-there-a-way-re-re-re -load-environment-in-emacs , но никакого хорошего решения не было дано.

Я использую EmacsClient с часто более чем 30 открытыми буферами, если я изменяю переменную окружения в оболочке, мне нужно выйти из EmacsClient (и заново открыть все буферы), или я должен вручную установить переменную окружения также в Emacs. Меня раздражает, что я не могу легко обновлять переменные окружения в Emacs. Какие-либо предложения?


Не существует прямого способа сделать это, потому что изменение переменной среды в родительском процессе не будет обновлять ее значение, экспортируемое в дочерний процесс.
Эрик Хетцнер,

Ответы:


7

exec-path-from-shell предоставляет exec-path-from-shell-copy-envкоманду, которая позволяет вам копировать значение переменных среды в сеансы Emacs. Например, также M-x exec-path-from-shell-copy-env RET FOOустанавливает значение $FOOв Emacs.

Обратите внимание, что exec-path-from-shell-copy-envсоздается новая оболочка для извлечения значения переменной среды. Следовательно, он будет работать только для переменных, которые вы установили в своих файлах конфигурации оболочки (например .bashrc), но не для переменных, установленных только во время сеанса оболочки с export. Извлечение этих переменных, как правило, невозможно без запутанных взломов, которые проверяют /proc/или подобные API для запуска процессов.


Что касается последних / переходных значений, если Emacs работает как сервер, то передача обновленных значений в emacsclient напрямую из этой оболочки будет достаточно простой.
Филс

@phils Спасибо, смотрите мой обновленный ответ ..
Håkon Hægland

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в командной строке оболочки, чтобы обновить переменные среды Emacs.


И вы можете запустить "printenv" изнутри функции тоже ...
mankoff

@mankoff На самом деле, я думаю, что вы не могли бы .. :) (Это напечатало бы старые значения тогда)
Håkon Hægland

Разве вы не можете создать оболочку с флагом входа? Или source.bashrc, .bash_profile и т. Д.?
mankoff

Да .. но это не помогло бы для особого случая, если я экспортирую в оболочке прямо из командной строки, используяexport VAR=value
Håkon Hægland

Да, я не думал об этом случае. Элегантное решение с клиентом!
mankoff

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
}

Позволяет экспортировать именованную переменную, например:

export EDITOR=vim
export-emacs EDITOR
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.