28

Обычно, если вы передаете команду ssh, как это

ssh me@example.com 'some-command.sh'

Вы получаете неинтерактивный сеанс, и ssh завершает работу, как только запускается команда (или сценарий, или что-то еще). Как я могу получить интерактивный сеанс, и при этом запустить команду, которую я указал, с моего локального компьютера. Например, я хотел бы иметь возможность открыть экран и перезапустить определенный сеанс экрана:

ssh me@example.com 'screen -r 12345'

но это не разрешено, возвращая ошибку "Должен быть подключен к терминалу". что, я полагаю, означает, по сути, "должен вызывать эту команду из интерактивной оболочки".

В качестве другого примера я использую тонну машин на работе, которые часто требуют от меня использования общей учетной записи, чтобы иметь права на определенные действия (да, я знаю: плохая идея, но не вините меня, я не настраивал такие путь), и они обычно имеют ksh в качестве оболочки по умолчанию. Я хотел бы войти в систему, переключиться на bash (или zsh) и получить исходный код моей учетной записи .bash_profile (или .zshrc). Это было бы легко, если бы я мог установить интерактивный сеанс SSH и передать команду на удаленный компьютер для запуска при входе в систему.

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

ОБНОВЛЕНИЕ: для тех, кто этого не осознавал, я не планирую делать все это вручную, поэтому, если вы откроете мне интерактивную сессию, а потом сделаете это вручную, то на самом деле ничего не решится.

2-е ОБНОВЛЕНИЕ: Чтобы попытаться еще раз уточнить: я пытаюсь выполнить (произвольные) команды на сервере (программно заданные на клиенте), но затем открыть интерактивный сеанс, на который влияет все, что сделано этими программными командами.

7 ответов7

23

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

ssh  -t hostname "bash --rcfile ~user/.bashrc"
10

Основываясь на ответе клана, полное решение выглядит так:

ssh -t user@server 'cd /a/great/place; bash'

Здесь я использую -t для принудительного выделения псевдотерминала, что требуется для интерактивной оболочки. Затем я выполняю две команды на сервере: сначала то, что я хотел сделать, прежде чем открывать интерактивную оболочку (в моем случае, изменение каталога на определенную папку), а затем саму интерактивную оболочку. Bash видит, что имеет псевдо-терминал, и отвечает в интерактивном режиме.

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

Еще раз спасибо dogbane за предоставление необходимой подсказки с -t . Раньше я решал эту проблему с expect , которое определенно убивает мышь из пушки. (:

2

Попробуйте это решение.

echo "command" | ssh user@remote_host

Логин является интерактивным, и ваша команда передается так, как если бы вы вводили ее в интерактивной командной строке. Сессия заканчивается, как если бы вы набрали

ssh user@remote_host 'command'
0

почему бы не установить detach в удаленной системе и использовать:

ssh -t user@example.com "/home/user/bin/detach ls"
0

Ответ laggingreflex близок ... Я бы изменил это следующим образом:

echo "command\n$(cat -)" | ssh user@remote_host

К сожалению, вам вряд ли понравится способ, который работает, потому что "cat" буферизует строки, которые он пишет в стандартный вывод ... Если мы создадим скрипт с именем «echo-cat», который будет выглядеть примерно так:

{
  echo "${@}"
 #cat buffers & won't flush to stdout immediately
 #cat -
  IFS='\n'
  while read line
  do
        echo "${line}"
  done
}

мы получим тот же результат без буферизации:

echo-cat "command" | ssh user@remote_host

Это, вероятно, приблизит вас к вашей цели ...

0

Это глупо и не проверено, но я думаю, что это должно работать.

Создайте скрипт с именем (например) remote-starter, который принимает аргумент в кавычках после аргумента user @ host:

remote-starter user@example.com 'some-command.sh arg1 arg2'

Этот сценарий должен сначала сохранить команду в кавычках (без кавычек) в файле с именем (например) .onetime на удаленном компьютере, а затем выполнить обычную команду ssh, на этот раз не передавая команду, которая будет выполняться на удаленном компьютере. (Если ssh user@example.com запущен из скрипта, он может запустить exec ssh user@example.com.)

Чтобы это работало, удаленный компьютер должен получить источник .onetime из своего .bash_profile или .zshrc или чего-то еще. После запуска .onetime он должен удалить .onetime , чтобы файл не запускался при следующем входе в систему.

0

Используйте ssh -X, чтобы использовать termIO cmds.

Кроме того - вы можете связать ваши cmds как "ssh 'source ~/.bashrc && cd && do'"

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .