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

29

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

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

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

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

plinehan
источник
Связанный stackoverflow.com/questions/24993598/ssh-then-change-shell
Тревор Бойд Смит

Ответы:

8

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

sysadmin1138
источник
1
Это то, что я в конце концов сделал, но с помощью scp. Отличная идея.
plinehan
16

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

ssh host.domain.com /bin/bash << EOF
big ugly commands
lots of them
EOF
Игнасио Васкес-Абрамс
источник
Вы не должны использовать "-s" для bash для чтения команд из stdin?
Weboide
Это не всегда требуется.
Игнасио Васкес-Абрамс
Я бы отказался, если бы мог, потому что это препятствует тому, чтобы команды имели доступ к stdin, и вопрос был о вызове определенной оболочки.
Эрик Вудрафф
3
@EricWoodruff, ... вызов конкретной оболочки (в данном случае bash) - это именно то , что показывает, как это сделать.
Чарльз Даффи
1
К вашему сведению, вы также можете сделать cat /tmp/tempfile_containing_your_script ssh ${hostname} /bin/bash. Таким образом, вместо одного шага у вас есть два шага: шаг 1, скопируйте ваш скрипт в файл, шаг 2, catв который скрипт ssh.
Тревор Бойд Смит
10

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

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

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

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

Курт Пфайфл
источник
Хорошая вещь. Этот рисунок на странице О'Рейли очень хорош. Однако в моем конкретном случае я хочу, чтобы это было возможно для любых пользователей, а не только для пользователей, которые правильно настроили свои ключи. У меня также нет root на компьютерах сервера, поэтому я не могу редактировать файлы вроде /etc/sshrc.
plinehan
Ну, это всегда сервер (или лучше: тот, кто осуществляет контроль над сервером), который вызывает выстрелы, когда вы подключаетесь к его сервису ... «Владелец» сервера решает, что с ним делать. - Вы не можете заставить что-либо «для любого пользователя (ей)», если у вас нет привилегий выше, чем у них.
Курт Пфайфл
Если клиент может запускать произвольные команды, он также может запускать произвольную оболочку в качестве команды.
Эрик Вудрафф
@ KurtPfeifle, что ссылка на О'Рейли не работает
Брайан Ванденберг
@BrianVandenberg: спасибо за подсказку. Я удалил эту ссылку сейчас.
Курт Пфайфл
2

Вы можете использовать -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 действовал как оболочка входа в систему, так что ваша оболочка тоже может иметь это.

Фабио Сантос
источник
1

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

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

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

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

Эрик Вудрафф
источник
1
Ничего удивительного. Удаленный демон ssh эффективно работает sh -c "$*". Итак, вы бежите sh -c "/bin/bash -c echo <(cat)"; сама echoкоманда является единственным передаваемым аргументом -c, и <(cat)вообще является отдельным аргументом.
Чарльз Даффи
0

Некоторое время назад я столкнулся с подобной ситуацией, когда мне нужно было использовать 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")
AWS
источник