Я пытаюсь получить shell-command
и async-shell-command
легко интегрировать с парой программ в моем .bashrc
файле, в частности, direnv в этом примере.
Я обнаружил, что если бы я настроил shell-command-switch
, я мог заставить процессы оболочки загружать мой профиль, как если бы это была обычная интерактивная оболочка входа в систему:
(setq shell-command-switch (purecopy "-ic")) (setqlicit-bash-args '("-ic" "export EMACS =; stty echo; bash"))
Я также использую exec-path-from-shell .
Скажем, у меня есть ~/.bashrc
файл с:
... eval "$ (direnv hook $ 0)" эхо "фу"
Внутри у ~/code/foo
меня есть .envrc
файл с:
экспорт PATH = $ PWD / bin: $ PATH эхо "бар"
Если я запускаю M-x shell
с default-directory
установленным на ~/code/foo
, оболочка bash правильно загрузит мой профиль и запустит ловушку direnv, чтобы добавить это к моему пути:
direnv: загрузка .envrc бар direnv: экспорт ~ PATH ~ / code / foo $ echo $ PATH / Users / имя пользователя / код / foo / bin: / usr / local / bin: ... # остаток $ PATH
Однако, если default-directory
все еще, ~/code/foo
и я запускаю M-! echo $PATH
, он корректно загружает мой .bashrc, но не выполняет ловушку direnv текущего каталога:
Foo / usr / local / bin: ... # остаток $ PATH без ./bin
Я получаю тот же результат, если я бегу M-! cd ~/code/foo && echo $PATH
.
Есть ли способ, которым я могу посоветовать или подключиться shell-command
или start-process
заставить его вести себя так, как будто он отправляется из интерактивного буфера оболочки?
источник
(setq shell-command-switch "-ic")
то он должен оцениваться вместе с любой другой командой в ~ / .bashrc.eval "$(direnv hook $0)"
. Это выполняется, но механизм, который должен срабатывать, когда вы находитесь в определенном каталоге с.envrc
файлом, не работает..envrc
файле не оценивается? Или это просто переменные среды, которые не экспортируются? Не могли бы вы привести полный пример, чтобы я мог попытаться воспроизвести это?Ответы:
Это не проблема для Emacs, а для bash.
shell-command
просто выполняетсяcall-process
на оболочке и передает аргументы. Я попробовал это на обычной оболочке:~/.bashrc
Источник, но ловушка direnv не запускается. Когдаdirenv hook bash
выполняется, функция_direnv_hook
выводится и добавляется кPROMPT_COMMAND
.Я подозреваю, что это
PROMPT_COMMAND
просто не сработает. Это не проблема, потому что_direnv_hook
это действительно просто. Мы можем просто добавитьeval $(direnv export bash)
команду shell, и она будет работать:Это распечатает расширенный путь к буферу сообщений. В качестве альтернативы выполните с
M-!
:Вам не нужно, чтобы
(setq shell-command-switch "-ic")
это работало.источник
eval "$(direnv export bash)"
включало бы добавление в elisp, но это было чрезвычайно полезно и поставило меня на правильный путь.Выполнение
eval "$(direnv hook $0)"
определяет функцию, к которой подключается$PROMPT_COMMAND
, которая никогда не вызывается при запуске bash,bash -ic
поскольку отсутствует приглашение. Вы можете изменить строку:eval "$(direnv hook $0)"
чтобы:
eval "$(direnv hook $0)" && _direnv_hook
явно вызвать функцию крючка.
Изменить: Только что понял, rekado дал очень похожий ответ.
источник
$PROMPT_COMMAND
.Спасибо Rekado и Erik за указание на то, как работает ловушка direnv с помощью
$PROMPT_COMMAND
. Посколькуshell-command
подсказка не используется, это не выполняется.Хотя ответ Эрика работает в моем примере вызова команды оболочки с
M-!
помощьюdefault-directory
set, он не будет работать в следующем примере:После некоторого поиска в Google, я нашел способ создать хеш preexec в bash для выполнения чего-либо перед выполнением команды. Я взял эту идею и изменил, чтобы соответствовать моей потребности в direnv. Вот как выглядит соответствующая часть моего ~ / .bashrc:
источник
в настоящее время вы, вероятно, захотите использовать https://github.com/wbolster/emacs-direnv
он работает аналогично хуку, который direnv устанавливает в вашей оболочке. среда emacs обновляется по запросу (или автоматически при переключении буферов), чтобы соответствовать тому, что указывает direnv, является правильной средой для текущего каталога.
путем изменения,
exec-path
иprocess-environment
emacs будет вести себя так, как ваша оболочка: выполнять программы с правильных путей и в правильной среде.источник