Перезавантажити змінні середовища


10

Це запитання було задано у суперпользователя - там є спосіб перезавантаження-середовища-змінних-в-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

@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 ..


І ви могли запустити "принтень" і з функції всередині ...
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
}

Дозволяє експортувати названу змінну, EG:

export EDITOR=vim
export-emacs EDITOR
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.