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

11

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

  1. Запустите сеанс SSH на удаленном компьютере с директивами из моего конфигурационного файла SSH (например ControlMaster auto)
  2. Этот сеанс запускает оболочку Z
  3. Он запускается .zshrcв моем «личном» каталоге (не в домашнем каталоге общего пользователя)

Было бы неплохо иметь псевдоним или простой способ запуска таких ssh-сессий (вот почему я подумал об использовании файла конфигурации OpenSSH), но я открыт для любых других идей!

Используете конфигурационный файл OpenSSH?

Я прочитал на справочной странице OpenSSH ssh_config, что могу использовать директиву, LocalCommandчтобы указать команду для локального запуска после успешного подключения к серверу. Это заставило меня подумать, что может быть способ сообщить configфайлу, какую команду запускать удаленно после подключения к серверу, но, похоже, ее нет.

Амелио Васкес-Рейна
источник
Я не думаю, что ты можешь. Но я озадачен, почему ты этого хочешь. В командной строке ssh уже есть команда. Почему ты не можешь бежать ssh mycommand? И если вы хотите выполнить какую-либо команду установки перед каждой командой, которая приходит через ssh, почему бы не настроить серверную часть?
Жиль "ТАК - перестань быть злым"
Спасибо @Guilles. Я нахожусь в ситуации, когда несколько пользователей используют одну и ту же удаленную учетную запись, поэтому я хотел бы быстро настроить несколько вещей при удаленном входе в систему. В частности, я хотел бы запустить оболочку Z и попросить ее запустить .zshrcв определенном каталоге (то есть в «личном» домашнем каталоге). Я пытался, ssh -t host_name 'zsh & source /path/to/my_zshrc'но это не сработало (у меня получилось FPATH variable not defined, и я думаю, что это потому, что zshфиниширует до того, как запустится my_zshrc, не говоря уже о том, что это не дало мне Z-оболочки)
Амелио Васкес-Рейна
Я думаю, что это заслуживает обновления OP, поэтому я просто обновил его.
Амелио Васкес-Рейна
Когда я искал похожий ответ, мне пришло в голову, что этот вопрос довольно близок к тому, что вы пытаетесь сделать.
Жиль "ТАК - перестань быть злым"

Ответы:

15

Наиболее очевидный способ выполнить команду удаленно - указать ее в командной строке ssh. Команда ssh всегда интерпретируется оболочкой удаленного пользователя.

ssh bob@example.com '. ~/.profile; command_that_needs_environment_variables'
ssh -t bob@example.com '. ~/.profile; exec zsh'

Общие учетные записи, как правило, плохая идея; если это вообще возможно, получить отдельные учетные записи для каждого пользователя. Если вы застряли с общей учетной записью, вы можете создать псевдоним:

ssh -t shared-account@example.com 'HOME=~/bob; . ~/.profile; exec zsh'

Если вы используете аутентификацию с открытым ключом (опять же, рекомендуется), вы можете определить команды для каждого ключа в ~/.ssh/authorized_keys. Смотрите этот ответ для более подробных объяснений. Отредактируйте строку для вашего ключа ~/.ssh/authorized_keysна сервере (все в одной строке):

command="HOME=$HOME/bob;
     if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then
       eval \"$SSH_ORIGINAL_COMMAND\";
     else exec \"$SHELL\"; fi" ssh-rsa AAAA…== bob@some.where
Жиль "ТАК - прекрати быть злым"
источник
Фантастический @Guilles. Ваш вклад в этот сайт делает его чрезвычайно полезным ресурсом для всех нас. Большое спасибо, правда. Кстати, я не знал о execкоманде. Чем exec zshотличается от звонка zshнапрямую? Почему это важно в данном конкретном случае?
Амелио Васкес-Рейна
Хм, когда я бегу, ssh -t shared-account@example.com 'HOME=~/bob; exec zsh'я получаю HOME=~/bob: command not found. Я думаю, что я на tcsh. У меня та же проблема, если я попытаюсь HOME=/home/bob. Я пробовал на bash и zsh. Любые подсказки, что может быть причиной этого? Наконец, оставит ли синтаксис выше с открытой сессией ssh? (что я хочу). Еще раз спасибо.
Амелио Васкес-Рейна
1
@intrpc execзаменяет оригинальную оболочку на zsh; без zshэтого исходная оболочка останется в памяти, пока zsh не выйдет и не завершится. Основное отличие - экономия памяти, это не очень важно. Если ваша оболочка входа в систему (t) csh, используйте setenv HOME ~/bob; exec zsh. Наконец, поскольку zsh запускается без аргументов, вы получаете сеанс оболочки, как если бы вы только что запустили sshи использовали zsh в качестве оболочки входа в систему.
Жиль "ТАК - перестань быть злым"
Еще раз спасибо за помощь. Один дополнительный вопрос здесь. Любой способ выполнить больше команд, после exec zshкоманды?
Амелио Васкес-Рейна
1
@ AmelioVazquez-Reina Не удобно, если у вас нет контроля над одним из файлов точек. Вы можете установить переменную окружения, ZDOTDIRчтобы заставить zsh искать точечные файлы в другом каталоге. Если у вас есть некоторый контроль над точечными файлами , то вы можете сделать что - то вроде дополнения eval $LC_STARTUP_CODEк $ZDOTDIR/.zshrcи передать код для выполнения в переменном окружении LC_STARTUP_CODE.
Жиль "ТАК - перестань быть злым"
-3

Чтобы выполнить команду удаленно после подключения к серверу, добавьте в файл .ssh / config следующий фрагмент

PermitLocalCommand yes

Host <server-ip-address>
    LocalCommand *command*
parth115
источник
2
Спасибо @ user626129, но, как я уже упоминал в первоначальном вопросе, LocalCommandдиректива заключается в запуске команды на локальной оболочке, а не на удаленной оболочке.
Амелио Васкес-Рейна