Как мне запустить команду sudo в Emacs? - PullRequest
14 голосов
/ 18 марта 2010

Я пытаюсь создать сочетания клавиш для некоторых часто используемых команд оболочки sudo (например, имея C-c s run (shell-command "sudo /etc/init.d/apache2 restart")).

Я попытался использовать прямой командный вызов оболочки, как указано выше, но он просто выводит в буфер *Shell Command Output* следующее:

[sudo] password for Inaimathi:
Sorry, try again.
[sudo] password for Inaimathi:
Sorry, try again.
[sudo] password for Inaimathi:
Sorry, try again.
sudo: 3 incorrect password attempts

На самом деле пароль не запрашивается. Я не хочу запускать Emacs, используя sudo emacs, но я думаю, что это вариант, если больше ничего не будет работать.

Идеальным решением была бы функция из Emacs (в отличие от jiggery-pokery для изменения поведения оболочки или команды sudo). Что-то вроде (sudo-shell-command "dostuff") или (with-password-prompt (shell-command "sudo dostuff")).

Ответы [ 7 ]

13 голосов
/ 18 марта 2010

Как насчет:

(shell-command (concat "echo " (shell-quote-argument (read-passwd "Password? "))
                       " | sudo -S your_command_here"))
11 голосов
/ 30 июля 2013

Я часто вызываю команды из Emacs, например aptitude update. Решение scottfrazer может быть не таким полезным. Синхронные команды заставляют меня долго ждать, и если вы запустите неподдерживаемую программу (например, aptitude, которая использует ncurses ), вы повесите Emacs ( Cg won не поможет), а загрузка процессора составит 100%. Изменение на async-shell-command решает эту проблему.

Но это также создает новую проблему. Если ваша команда не выполнена, ваш пароль окажется в буфере *Messages*:

echo PASSWORD | sudo -S aptitude: exited abnormally with code 1.

Вот почему я предлагаю следующее решение:

(defun sudo-shell-command (command)
  (interactive "MShell command (root): ")
  (with-temp-buffer
    (cd "/sudo::/")
    (async-shell-command command)))

Здесь "M" в interactive запрашивает имя программы в минибуфере, with-temp-buffer создает поддельный буфер, в котором мы меняем каталог на /sudo::/, чтобы использовать TRAMP для приглашения sudo.

Это решение Дэвида Каструпа из команды sudo с подсказкой пароля минибуфера @ gnu.emacs.help .

Обратите внимание, что вы все равно не должны вызывать aptitude напрямую, иначе подпроцесс будет там всегда, пока вы не отправите sudo pkill aptitude.

Читайте оболочки и процессы в ручном режиме.

4 голосов
/ 18 марта 2010

Если вы работаете с emacs22 или новее, вы можете просто запустить оболочку из emacs и запустить там команду sudo. Он автоматически выведет вас в окно минибуфера для вашего пароля:

M-x shell
sudo whoami

Это просто спросит ваш пароль внизу экрана ( без его отображения).

3 голосов
/ 18 марта 2010

Обходной путь (вместо решения emacs):

Установите пару ключей ssh, чтобы пароль не требовался.

Процедура:

  1. запустить ssh-keygen, чтобы сгенерировать пару ключей. Дайте им полезное имя, чтобы они отличались от всех остальных, которые вы сделаете, когда привыкнете к этому
  2. Скопируйте общедоступный один на $HOME/.ssh для получающего счета
  3. Оставьте личный один в $HOME/.ssh отправляющей учетной записи (вы можете скопировать ее на несколько отправляющих учетных записей, но может быть лучше создать отдельную пару ключей для каждой входящей машины)
  4. изменить $HOME/.ssh/config на отправляющей машине, чтобы сообщить ssh, какой ключ использовать
  5. Прибыль
1 голос
/ 18 марта 2010

РЕДАКТИРОВАТЬ: ответ Скотта выше гораздо предпочтительнее этого взломать. Используйте это.

Возможное решение:

Я обнаружил, что установка утилиты для запроса пароля по умолчанию решает эту проблему.

Что мне нужно было сделать, это добавить Defaults:ALL askpass=/usr/lib/openssh/gnome-ssh-askpass в мой /etc/sudoers файл (очевидно, используя sudo visudo).

Eval-ing (shell-command "sudo /etc/init.d/apache2 restart") теперь запрашивает у меня пароль, а не пытается угадать его безуспешно.

Я не приму этот ответ, если не станет ясно, что лучшего решения не существует; в идеале я хотел бы что-то, что решит проблему внутри Emacs вместо того, чтобы требовать, чтобы вы ковырялись в каталоге /etc.

1 голос
/ 18 марта 2010

sudo пытается открыть терминальное устройство (tty) для чтения пароля. Ваш процесс emacs может не иметь управляющего терминала. sudo -S говорит ему использовать стандартный ввод для пароля, который должен прийти из emacs.

0 голосов
/ 18 марта 2010

Я использовал следующее для запуска nmap из emacs как root,

http://nakkaya.com/sudoEl.markdown

...