Ssh, выполнить команду при входе в систему, а затем оставаться в системе?

29

Я попробовал это с ожидаемым, но это не сработало: оно закрыло соединение в конце.

Можем ли мы запустить скрипт через ssh, который будет входить на удаленные машины, запускать команды и не отключаться?

Таким образом, ssh на машине, перейдите в такой-то каталог, а затем выполните команду и оставайтесь в системе.

-Джонатан

(ожидаю, что я использовал)

#!/usr/bin/expect -f
set password [lrange $argv 0 0]
spawn ssh root@marlboro "cd /tmp; ls -altr | tail"
expect "?assword:*"
send -- "$password\r"
send -- "\r"
interact
Джонатан
источник
9
Это только я или вы "автоматизируете" аутентификацию по паролю таким образом, вместо использования pubkeys или другого вменяемого метода?
Гравитация

Ответы:

25

Добавить ; /bin/bashв конец командной строки на удаленной стороне? То есть:

spawn ssh -t root@marlboro "cd /tmp; ls -altr | tail; /bin/bash -i"

Более того, измените .bashrc root на что-то вроде этого:

PROMPT_COMMAND="cd /tmp && ls -altr | tail ; unset PROMPT_COMMAND"

:)

Билл Вайс
источник
2
Вы можете добавить -iк этому bash.
Тедди
Да, я полагаю :)
Билл Вайс
Когда я делаю это, в новой оболочке происходит разрыв табуляции (даже с "-i") - есть идеи, почему / как это исправить?
Coderer
1
Я проверил мой новый ответ здесь, он прекрасно работает. Немного грубо, но это работает.
Билл Вайс
7
Попробуйте ssh -tвыделить pty.
Приостановлено до дальнейшего уведомления.
4

Если вы в порядке с этим в Python, у pexpect есть пример, который делает почти то, что вы просите:

import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('noah@example.com')
child.expect ('ftp> ')
child.sendline ('ls /pub/OpenBSD/')
child.expect ('ftp> ')
print child.before   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

Чтобы сделать это с помощью ssh вместо ftp, вам понадобится код, подобный следующему (файлы примеров в pexpect содержат гораздо больше деталей и информации, но вот основы):

import pexpect
child = pexpect.spawn ('ssh root@marlboro')
child.expect ('Password:')
child.sendline ('password')
child.expect ('prompt# ')
child.sendline ('cd /tmp')
child.expect ('prompt# ')
child.sendline ('ls -altr | tail')
child.expect ('prompt# ')
print child.before, child.after   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

Не поймите меня неправильно, я ЛЮБЛЮ ожидаю (особенно автоэкспертиза), но python просто так намного проще для меня.

Джед Дэниелс
источник
Я тоже перехожу от ожидания к pexpect. Python теперь гораздо более распространен.
Дж. М. Беккер
4

Вероятно, самый простой и чистый способ подключиться по ssh к серверу, создать интерактивную оболочку и выполнить команды внутри этой оболочки - создать собственный rc-файл для bash.

В своем пользовательском файле bashrc на сервере сначала укажите файл по умолчанию, а затем добавьте свои пользовательские команды, например

~ / .Bashrc_custom:

. ~/.bashrc
cd dir/
workon virtualenvproject

Затем вы можете начать сеанс SSH следующим образом:

$ ssh -t server "/bin/bash --rcfile ~/.bashrc_custom -i"

В -tопции силы на выделение псевдо-терминал, так что такие вещи , как закладка заканчивания работы.

В --rcfileопции определяет , какой файл конфигурации для загрузки вместо заданного по умолчанию. Важно: вы должны поместить «аргументы с двойной чертой» в командную строку перед односимвольными параметрами, чтобы их можно было распознать.

-iАргумент / бен / Баш есть для вызова интерактивной оболочки.

Данило Барген
источник
вообще-то нет. Что делать, если я хочу запускать разные команды для каждого соединения?
Евгений Коньков
1

Если кому-то нужна информация о том, что происходит в фоновом режиме, вы должны взглянуть на руководство по sshd:

Когда пользователь успешно входит в систему, sshd делает следующее:

  1. Если для входа используется tty, а команда не указана, печатается время последнего входа в систему и / etc / motd (если это не запрещено в файле конфигурации или с помощью ~ / .hushlogin; см. Раздел «ФАЙЛЫ»).
  2. Если логин на tty, записывает время входа.
  3. Проверяет / etc / nologin и / var / run / nologin; если он существует, он печатает содержимое и завершает работу (если не root).
  4. Изменения для запуска с правами обычного пользователя.
  5. Устанавливает основную среду.
  6. Читает файл ~ / .ssh / environment, если он существует, и пользователям разрешено изменять свою среду. Смотрите параметр PermitUserEnvironment в sshd_config (5).
  7. Изменения в домашнем каталоге пользователя.
  8. Если ~ / .ssh / rc существует, запускает его; иначе, если / etc / ssh / sshrc существует, запускает его; в противном случае выполняется xauth (1). Файлы `` rc '' получают протокол аутентификации X11 и cookie при стандартном вводе. Смотрите SSHRC ниже.
  9. Запускает пользовательскую оболочку или команду.

https://www.freebsd.org/cgi/man.cgi?sshd(8)#LOGIN_PROCESS

Gerry
источник
0

Как правило, вы должны избегать использования ssh таким способом, поскольку он побеждает его цель.
Сделать

ssh-add -l | grep "file_of_your_rsa_priv_key_here"

чтобы увидеть, указан ли ваш ключ в пуле активных сессий ssh, или добавить его самостоятельно (с помощью ssh-add).

Kounavi
источник