Làm cách nào tôi có thể sử dụng ứng dụng khách Emacs cục bộ của mình làm $ EDITOR cho các máy từ xa mà tôi truy cập qua TRAMP?


44

Tôi thường sử dụng TRAMP để quản lý một số máy chủ từ xa, cả để chỉnh sửa tệp và chạy shell từ xa shell-mode. Tuy nhiên, điều này không hoạt động khi một lệnh sử dụng EDITORbiến để chỉnh sửa tệp, crontab -eđặc biệt là vì shell-modelà một thiết bị đầu cuối "ngu ngốc" không hỗ trợ chạy trình soạn thảo khác bên trong nó.

Tại địa phương, tôi làm điều này với một cuộc gọi thích hợp để emacsclientmở ra một bộ đệm mới và làm cho cuộc sống rất dễ dàng. Thật không may, điều này không hoạt động từ máy từ xa.

Tôi đoán tôi có thể sử dụng ed. (Hừ!)

Làm cách nào tôi có thể thiết lập một điều khiển từ xa EDITORcho phép tôi chỉnh sửa các tệp với phiên bản Emacs cục bộ của mình?

Câu trả lời:


23

[LƯU Ý] câu trả lời này đã được chỉnh sửa rất nhiều để theo dõi các cập nhật của with-editorsự phát triển. Hầu hết các ý kiến ​​có thể sẽ không có ý nghĩa nhiều nữa. Có một số ý kiến mới mà làm có ý nghĩa.


Magit chứa một thư viện có tên with-editortại https://github.com/magit/with-editor cho phép bạn sử dụng Emacs cục bộ của mình dưới dạng $ EDITOR trên các máy từ xa qua TRAMP.

Một cách khác là https://github.com/habnabit/remote-emacsclient , nhưng có vẻ phức tạp hơn & ít chung chung hơn.

Cách đơn giản nhất để cài đặt with-editorlà thông qua MELPA:

M-x package-install with-editor

Nếu không, chỉ cần lấy https://github.com/magit/with-editor/blob/master/with-editor.el ở đâu đó vào đường dẫn tải của bạn và requirenó (nó cũng phụ thuộc vào dấu gạch ngang).

Sau đó, bạn chỉ cần bắt đầu shell, eshellhay ansi-termvà làm như sau:

M-x with-editor-export-editor

Nó sẽ hỏi bạn $ EDITOR nào mà bạn quan tâm, chỉ cần nhấn enter cho EDITORbiến mặc định . Sau đó, bên trong shell, bạn có thể nhập crontab -evà chỉnh sửa crontab của mình trong emacs. Nhấn C-c C-cđể lưu crontab hoặc C-c C-kđể hủy chỉnh sửa.

Nếu bạn muốn thiết lập lâu dài hơn:

(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)

Ngoài ra, bạn có thể sử dụng M-x with-editor-async-shell-command crontab -e RETcho các lệnh nhanh chóng.


Bạn có thể giải thích làm thế nào with-editorthư viện này liên quan đến câu hỏi? Âm thanh hữu ích
Malabarba

@Silex: Tôi có cần đặt $EDITORbiến thành một cái gì đó trên máy từ xa để nó hoạt động không? Nó chỉ móc vào emacsclient?
Tikhon Jelvis

Nhưng vâng, điều này trông giống như những gì tôi muốn. Tôi sẽ phải dùng thử bằng cách nào đó. Tôi cho rằng nó có thể được cài đặt bằng chính nó, mà không cần phần còn lại của chi nhánh?
Tikhon Jelvis

1
@TikhonJelvi: nó chắc chắn sẽ có thể tự cài đặt được, nhưng bây giờ nó chỉ là một phần của nó git-modes. Tôi đang theo dõi lib này một cách chặt chẽ và chỉ là tác giả của nó (@tarsius) đang bận rộn với việc phát hành phép thuật, nhưng cuối cùng nó sẽ là một gói của riêng nó. Về $ EDITOR, bạn không cần phải tự đặt nó thành bất cứ điều gì, nó được thực hiện khi cần thiết khi bạn chạy bất kỳ lệnh nào sử dụng nó. Magit sử dụng lib này với $ GIT_EDITOR.
Silex

1
Lưu ý này sẽ ngừng làm việc, kể sshing đến một từ xa từ bên trong một hiện shell-mode/ term-modeđệm. Điều này có thể được giải quyết với một số cấu hình bổ sung, xem emacs.stackexchange.com/questions/5589/ mẹo . Nếu bạn làm cho nó hoạt động, thì vui lòng báo cáo kết quả của bạn tại github.com/magit/magit/issues/1638 .
tarsius

1

Tuyên bố miễn trừ trách nhiệm: Tôi chưa thử điều này.

Bạn có thể có được một phần của cách này bằng cách có một đầu ra lệnh theo dõi chức năng cho một lệnh để mở tệp bằng TRAMP. Lỗ hổng bảo mật? Đúng. Chức năng? Có lẽ.

Sử dụng một shell-modecái móc để thêm một cái móc after-change-hookvào shell-mode. Móc đồng hồ này cho một trình tự cụ thể. Thí dụ:

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

Sau đó, nó sử dụng tramp-find-fileđể mở tập tin. Điều này tương đối an toàn bởi vì điều duy nhất mà điều khiển từ xa có thể làm là kích hoạt a tramp-find-file. Một xác nhận đầu tiên sẽ là tốt nhưng tùy chọn.

Khi chỉnh sửa xong, một hook khác có thể kích hoạt lối ra của chương trình giả (ví dụ bằng cách gửi C-c).

Trường hợp xấu nhất (về bảo mật) là họ tìm cách chạy mã tùy ý. Nếu bạn có các biến bộ đệm được đặt để luôn luôn đánh giá, kẻ tấn công độc hại có thể ghi đè lên các cài đặt quan trọng mà bạn không biết. Họ cũng có thể khởi động một cuộc tấn công từ chối dịch vụ bằng cách khiến nhiều bộ đệm mở ra. Xác nhận có khả năng có thể ngăn chặn tất cả các bên trên.

Chương trình trên điều khiển từ xa có thể được triển khai tầm thường trong C (hoặc bất kỳ ngôn ngữ nào khác).


1

https://stackoverflow.com/questions/2231902/originate-edit-of-remote-file-USE-emacs-tramp-from-ssh-session có một câu trả lời khá đơn giản được chấp nhận

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

và sau đó sử dụng

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

Ngoài ra còn có https://stackoverflow.com/questions/12546722/USE-emacs-server-and-emacsclient-on-other-machines-as-other-users phức tạp hơn nhưng trong đó các câu trả lời cũng (tương tự) chạm tương tự căn cứ.


1

Tôi có một đoạn script nhỏ trong đường dẫn của tôi trên máy chủ từ xa ~/bin/ec, tốc ký cho 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[@]}"

Kịch bản lệnh này chuyển -nvà lập luận +không thay đổi thành emacsclient, nếu không thì các đối số được coi là các tệp để Emacs cục bộ của bạn mở. Mỗi tệp có tiền tố với giao thức TRAMP và máy chủ lưu trữ để Emacs biết cách mở nó. Bạn có thể thay đổi ssh:sang một giao thức TRAMP khác nếu muốn.

Bạn phải thay thế zbằng tên máy chủ của máy từ xa. Điều này được sử dụng bởi Emacs cục bộ để kết nối thông qua TRAMP. (Bạn có thể có thể sử dụng hostnamevào đây để tính tổng quát. Tôi thích sử dụng các mục nhỏ như ztrong địa phương của tôi ssh_configcho ngắn gọn, và điều khiển từ xa không có ý tưởng tôi đang làm điều này. Hãy thử nó!)

Sử dụng:

  • ec file trong shell từ xa mở tập tin trong Emacs cục bộ và chờ đợi
  • ec -n file trong shell từ xa mở tập tin trong Emacs cục bộ và trả về
  • export EDITOR=~/bin/ecở xa .bashrclàm cho phép thuật xảy ra

Để đảm bảo servertệp của tôi tốt, tôi có tệp này trong địa phương của mình .emacs, một lần nữa sử dụng tên máy chủ nhỏ 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)

Cổng 9999 là RemoteForward. Tôi đặt cái này ở địa phương ~/.ssh/ssh_configđể tự động chuyển tiếp, cộng với công cụ ControlMaster cho tốc độ.

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

Cuối cùng, hãy đảm bảo TRAMP biết về bạn ssh_confignếu bạn sử dụng nó:

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

0

Có thể cần một chút tinh chỉnh, nhưng đây là ý tưởng:

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

1
Bạn có nghĩa là quay trở lại từ máy chủ từ xa đến máy khách nơi Emacs đang chạy? Điều đó thường không thể.
Gilles 'SO- ngừng trở nên xấu xa'

Chà, nếu bạn không thể tiếp cận khách hàng nơi Emacs đang chạy, thì không thể làm gì được.
artagnon

2
Bạn có thể yêu cầu ssh, thông qua nó ~ / .ssh / config để luôn chuyển tiếp trình nghe ssh cục bộ tới một cổng trên máy từ xa. Có lẽ bạn cũng muốn chuyển tiếp đại lý ssh của mình, mặc dù ý kiến ​​khác nhau về mức độ an toàn của nó. Điều này sẽ cho phép bạn có thể quay lại bằng cách thực hiện EDITOR = "ssh $ user @ localhost: 1234 ..."
Ben Hyde

Một tùy chọn khác có lẽ là viết một trình bao bọc nhỏ để gọi edit-server.el
stsquad

0

Harold Abnabit đã đưa ra cách tiếp cận này 1 :

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

1 dựa trên một bài viết trước đó của Ryan Barrett (mà anh ấy liên kết).

FWIW cũng có https://stackoverflow.com/q/5154224/324105 trong đó Petri Lehtinen đã đưa ra https://gist.github.com/akheron/850795 . Tôi tưởng tượng các giải pháp phức tạp hơn là tốt hơn, nhưng một cách tiếp cận rất đơn giản vẫn có thể được quan tâm.


0

Thực sự ngạc nhiên chưa ai nhắc đến sshfs. Đây là những gì tôi thường làm khi đi từ xa:

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

Mặc dù multi-termkhông đồng bộ hóa thư mục làm việc cục bộ với thư mục từ xa, nhưng nó đánh bại tất cả các giải pháp khác mà tôi đã thử bằng một cú sút xa. Mặc dù theo dõi dir sẽ là một tính năng được chào đón chắc chắn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.