Заставить SSH использовать определенную оболочку

Есть ли способ заставить SSH использовать определенную оболочку на удаленном конце, независимо от того, какая оболочка пользователя по умолчанию?

Я пробовал решения, похожие на:

ssh host.domain.com /bin/bash -c 'complicated, multi-line command'

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

7 ответов

Решение

Я не верю, что это возможно, по крайней мере, с системами на основе openssh. Если у вас есть такая возможность, лучшим решением может быть создание файла сценария оболочки, а затем выполнение его с помощью опубликованного вами метода. Преимущество было бы в том, чтобы минимизировать количество необходимых экранирований, но оставило бы файл, который пришлось бы удалить (возможно, в качестве последнего шага сценария).

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

С помощью этой техники вы можете не только использовать любую установленную оболочку, но также вы можете открывать vim и другие программы, для которых требуется TTY, из одной команды. Что здорово, если вы пишете сценарий оболочки, который регистрирует вас где-то и открывает файл на vim, или htop, или что-то в этом роде.

me@my-machine $ ssh root@myhost -t bash
root@myhost:~# exit
Connection to myhost closed.
me@my-machine $ ssh root@myhost -t sh
# exit
Connection to myhost closed.
me@my-machine $ 

Не уверен, является ли это оболочкой входа в систему, но есть варианты, чтобы bash действовал как оболочка входа в систему, так что ваша оболочка тоже может иметь это.

Используйте наследственность:

ssh host.domain.com /bin/bash << EOF
big ugly commands
lots of them
EOF

Используйте основанные на ключах логины, а не пароли. Затем вы можете добавить (список) "принудительных команд (ы)" к вашему общедоступному ключу ssh (в поле "опции" в случае SSH1), который установлен на сервере (в файле ~/.ssh/authorized_keys для SSH1, ~ /.ssh2 / авторизация для SSH2).

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

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

Читайте о "принудительных командах" через Google.

Удивительно, но я вижу разные результаты со следующим:

бежать в тире:

ssh eric@172.17.1.241 /bin/bash -c "echo <(cat)"                                              
sh: 1: Syntax error: "(" unexpected

против Баш:

ssh eric@172.17.1.241 '/bin/bash -c "echo <(cat)"'                                            
/dev/fd/63

Показ полностью цитируемой команды работает, как и ожидалось.

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

      $ cat command.txt
echo $BASH

$ cat command.txt | ssh me@host /bin/bash
/bin/bash

$ cat command.txt | ssh me@host /bin/sh
/bin/sh

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

Один из способов сделать это - передать всю зависимую команду в одну строку (use;) в /usr/bin/ksh на удаленной машине. например:

host="user@host"

db_conn="ora_user/passwd"

a="select * from dual;"

frmt="set heading off echo off feedback off verify off pagesize 0 termout off"

var=$(ssh ${host} "echo 'sqlplus -silent /nolog |&; sql_pid=\$!; print -p \"conn ${db_conn}\"; print -p \"${frmt}\"; print -p \"${a}\"; print -p \"exit\"; wait \$sql_pid' > /remote_dir/kshcmd.txt; awk '{print \$0}' /remote_dir/kshcmd.txt | /usr/bin/ksh")
Другие вопросы по тегам