Як я можу використовувати свого локального клієнта Emacs як $ EDITOR для віддалених машин, до яких я отримую доступ через TRAMP?


44

Я часто використовую TRAMP для управління кількома віддаленими серверами, як для редагування файлів, так і для запуску віддалених оболонок shell-mode. Однак це не працює, коли команда використовує EDITORзмінну для редагування файлу, наприклад, crontab -eтому що shell-modeце "німий" термінал, який не підтримує запуск іншого редактора всередині нього.

Місцево я роблю це за допомогою відповідного дзвінка, emacsclientякий відкриває новий буфер і робить життя дуже легким. На жаль, це не працює з віддаленої машини.

Я думаю, я міг би скористатися ed. (Га!)

Як я можу налаштувати пульт, EDITORякий дозволив би мені редагувати файли з моїм локальним екземпляром Emacs?

Відповіді:


23

[ПРИМІТКА] Ця відповідь була сильно відредагована, щоб слідкувати за оновленнями with-editorподій. Більшість коментарів, ймовірно, більше не матимуть сенсу. Є нові коментарі, які мають сенс.


Magit містить бібліотеку з іменем, with-editorдоступну за посиланням https://github.com/magit/with-editor, яка дозволяє використовувати ваш локальний Emacs як $ EDITOR на віддалених машинах через TRAMP.

Ще одна альтернатива - https://github.com/habnabit/remote-emacsclient , але вона здається більш складною та менш загальною.

Найпростіший спосіб встановлення with-editor- через MELPA:

M-x package-install with-editor

В іншому випадку просто схопіть https://github.com/magit/with-editor/blob/master/with-editor.el десь до вашого шляху завантаження, і requireвін (це також залежить від тире).

Потім просто почати shell, eshellабо ansi-termі виконайте наступні дії :

M-x with-editor-export-editor

Він запитає, який саме $ EDITOR вас цікавить, просто натисніть клавішу enter для EDITORзмінної за замовчуванням . Потім всередині оболонки ви можете ввести crontab -eта відредагувати свій crontab в emacs. Натисніть, C-c C-cщоб зберегти літопис або C-c C-kскасувати редагування.

Якщо ви хочете більш постійного налаштування:

(add-hook 'shell-mode-hook  'with-editor-export-editor)
(add-hook 'term-mode-hook   'with-editor-export-editor)
(add-hook 'eshell-mode-hook 'with-editor-export-editor)

Крім того, ви можете використовувати M-x with-editor-async-shell-command crontab -e RETдля швидких команд.


Не могли б ви детальніше розповісти, як ця with-editorбібліотека стосується питання? Звучить корисно
Малабарба

@Silex: Чи потрібно мені встановити $EDITORзмінну на щось на віддаленій машині, щоб це працювало? Це просто зачепить emacsclient?
Тихон Єлвіс

Але так, це виглядає саме те, що я хочу. Мені доведеться якось спробувати - я припускаю, що його можна встановити сам, без іншої гілки?
Тихон Єлвіс

1
@TikhonJelvi: це, безумовно, буде встановлено самостійно, але поки це лише частина git-modes. Я уважно стежу за цією лібкою, і просто її автор (@tarsius) зайнятий випуском магіту, але врешті-решт це буде власний пакет. Щодо $ EDITOR, вам не потрібно встановлювати це на що-небудь самостійно, це робиться, коли потрібно, коли ви запускаєте будь-які команди, які використовують. Magit використовує цю лібу з $ GIT_EDITOR.
Silex

1
Зверніть увагу, що це припинить роботу після передачі на віддалене місце з існуючого shell-mode/ term-modeбуфера. Це можна вирішити за допомогою додаткової конфігурації, див. Emacs.stackexchange.com/questions/5589/… . Якщо ви все-таки працюєте, повідомте про свої результати на github.com/magit/magit/isissue/1638 .
Тарсій

1

Відмова: Я цього не пробував.

Ви можете отримати частину шляху, отримавши команду для перегляду функцій для команди, щоб відкрити файл за допомогою TRAMP. Захищений отвір? Так. Функціональний? Мабуть.

Використовуйте shell-modeгак , щоб додати гак after-change-hookв shell-mode. Цей гачок спостерігає за певною послідовністю. Приклад:

;; RemoteTRAMP token: <authentication token maybe?>
;; RemoteTRAMP edit: /path/to/my/file

Потім він використовується tramp-find-fileдля відкриття файлу. Це відносно безпечно, оскільки ТОЛЬКІ ЧОГО, що дистанційний може зробити, це тригер a tramp-find-file. Спочатку підтвердження було б добре, але необов’язково.

Коли редагування закінчено, інший гак може спровокувати вихід фіктивної програми (наприклад, надсиланням C-c).

Найгірший випадок (для безпеки) полягає в тому, що вони знаходять спосіб запустити довільний код. Якщо у вас буферні змінні налаштовані завжди оцінювати, зловмисний зловмисник може замінити важливі параметри без вашого відома. Вони також можуть запустити атаку відмови в службі, викликаючи відкриття багатьох буферів. Підтвердження можуть, ймовірно, перешкодити всьому вищесказаному.

Програма на пульті дистанційно може бути реалізована на C (або будь-якій іншій мові).


1

https://stackoverflow.com/questions/2231902/originate-edit-of-remote-file-using-emacs-tramp-from-ssh-session має досить просту прийняту відповідь, яка дорівнює

(setq server-use-tcp t)
(setq server-host "name_of_local_machine")
(server-start)
;; Maybe also muck with `server-auth-dir`

а потім використовувати

emacsclient -f ~/.emacs.d/server/server /`hostname`:/path/to/local/file

Є також https://stackoverflow.com/questions/12546722/using-emacs-server-and-emacsclient-on-other-machines-as-other-users, який є складнішим, але де відповіді також (приблизно) стосуються подібних бази.


1

У мене є крихітний сценарій на моєму шляху на віддаленому хості в ~/bin/ec, скорочення для emacsclient.

#!/bin/bash

params=()
for p in "$@"; do
  if [ "$p" == "-n" ]; then
    params+=( "$p" )
  elif [ "${p:0:1}" == "+" ]; then
    params+=( "$p" )
  else
    params+=( "/ssh:z:"$(readlink -f $p) )
  fi
done
emacsclient --server-file=$HOME/.emacs.d/server/server "${params[@]}"

Цей скрипт передається -nі +аргументується незмінним до emacsclient, інакше аргументи розглядаються як файли для відкриття локального Emacs. Кожен файл є префіксом протоколу TRAMP і хостом, тому Emacs знає, як його відкрити. Можливо, ви зможете перейти ssh:на інший протокол TRAMP, якщо хочете.

Ви повинні замінити zім'я хоста віддаленої машини. Це використовується місцевим Emacs для підключення через TRAMP. (Ви можете використати hostnameтут для загальності. Я віддаю перевагу коротким записам, як zу моїх місцевих, ssh_configдля стислості, а пульт не має уявлення, я це роблю. Спробуйте!)

Використання:

  • ec file у віддаленій оболонці відкривається файл у локальному Emacs та чекає
  • ec -n file у віддаленій оболонці відкривається файл у локальному Emacs та повертається
  • export EDITOR=~/bin/ecу віддаленому .bashrcвідтворює магію

Щоб мій serverфайл був хорошим, я маю це в моєму локальному .emacsрегіоні, знову використовуючи крихітне ім’я хоста z:

(setq server-use-tcp t
      server-port    9999)
(defun server-start-and-copy ()
  "Start server and copy server file to remote box."
  (interactive)
  (server-start)
  (copy-file "~/.emacs.d/server/server" "/z:.emacs.d/server/server" t)
  (chmod "/z:.emacs.d/server/server" (string-to-number "644" 8))
  )
(add-hook 'emacs-startup-hook 'server-start-and-copy)

Порт 9999 - RemoteForward. Я поклав це в моє місцеве місце ~/.ssh/ssh_configдля автоматизації переадресації, плюс речі ControlMaster для швидкості.

Host z
HostName dev.example.com
User dev
ControlMaster auto
ControlPath ~/.ssh/z.sock
RemoteForward 9999 localhost:9999

Нарешті, переконайтеся, що TRAMP знає про ваше, ssh_configякщо ви використовуєте його:

(require 'tramp)
(tramp-set-completion-function "ssh"
  '((tramp-parse-sconfig "~/.ssh/config")))

0

Може знадобитися трохи налаштувати, але ось ідея:

EDITOR="ssh artagnon@luneth \"emacsclient -n /`hostname`:$1\""

1
Ви маєте на увазі ssh'ing назад з віддаленого сервера до клієнта, де працює Emacs? Це часто неможливо.
Жил "ТАК - перестань бути злим"

Що ж, якщо ви не можете зайти до клієнта, де працює Emacs, зробити це неможливо.
артаньйон

2
Ви можете запитати ssh через ~ / .ssh / config, щоб завжди пересилати локального слухача ssh до порту на віддаленій машині. Ви, ймовірно, хочете також переслати свій ssh-агент, хоча думки відрізняються щодо того, наскільки це безпечно. Це дозволить вам повернутися, виконавши EDITOR = "ssh $ user @ localhost: 1234 ..."
Бен Хайд

Іншим варіантом, можливо, буде написання маленької обгортки для виклику edit-server.el
stsquad

0

Гарольд Абнабіт придумав такий підхід 1 :

http://blog.habnab.it/blog/2013/06/25/emacsclient-and-tramp/

1 заснований на попередній статті Райана Барретта (на яку він посилається).

FWIW також є https://stackoverflow.com/q/5154224/324105, в якому Петрі Лехтінен придумав https://gist.github.com/akheron/850795 . Я думаю, що складніші рішення краще, але дуже простий підхід все ще може зацікавити.


0

Дійсно здивований ще ніхто не згадав sshfs. Це те, що я зазвичай роблю, коли йду віддалено:

1) multi-term; sshfs user@host:/dir/i/want/ /mnt/point/on/my/machine
2) open whatever I want to edit in my local emacs
3) get-term; ssh user@host to launch executables etc

Хоча multi-termне синхронізується локальний робочий режим з віддаленим режимом, він перемагає всі інші рішення, які я спробував давно. Хоча відстеження режисура було б точно бажаною функцією.

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