Каков самый чистый способ ssh и запустить несколько команд в Bash?
У меня уже настроен агент ssh, и я могу запускать команды на внешнем сервере в Bash script, делая такие вещи, как:
ssh blah_server "ls; pwd;"
Теперь, что я действительно хотел бы сделать, это запустить много длинных команд на внешнем сервере. Закрытие всех этих элементов между кавычками было бы довольно уродливым, и я бы предпочел бы избегать ssh'ing несколько раз, чтобы этого избежать.
Итак, есть ли способ сделать это за один раз, заключенный в круглые скобки или что-то еще? Я ищу что-то вроде:
ssh blah_server (
ls some_folder;
./someaction.sh;
pwd;
)
В принципе, я буду доволен любым решением, если оно будет чистым.
Изменить
Чтобы уточнить, я говорю о том, что это часть более крупного Bash script. Другим людям, возможно, придется иметь дело с script вниз по линии, поэтому я хочу сохранить его в чистоте. Я не хочу иметь Bash script с одной строкой, которая выглядит так:
ssh blah_server "ls some_folder; ./someaction.sh 'some params'; pwd; ./some_other_action 'other params';"
потому что это чрезвычайно уродливо и трудно читать.
Ответы
Ответ 1
Как насчет Bash Здесь Документ:
ssh otherhost < < EOF ls some_folder;. /someaction.sh 'некоторые параметры' PWD. /some _other_action 'другие параметры'
EOF
Код>
Чтобы избежать проблем, упомянутых в комментариях к @Globalz, вы можете (в зависимости от того, что вы делаете на удаленном сайте) уйти с заменой первой строки
ssh otherhost/bin/bash < < EOF
Код>
Обратите внимание, что вы можете сделать замену переменных в документе Here, но вам, возможно, придется решать проблемы с цитированием. Например, если вы укажете "предельную строку" (т.е. EOF
в приведенном выше примере), то вы не сможете делать замены переменных. Но без цитирования предельной строки заменяются переменные. Например, если вы определили $NAME
выше в своем сценарии оболочки, вы можете сделать
ssh otherhost/bin/bash < < EOF
touch "/tmp/${NAME}"
EOF
Код>
и он создаст файл в целевом otherhost
с именем того, что вы назначили $NAME
. Другие правила о цитировании оболочки script также применимы, но слишком сложны для перехода сюда.
Ответ 2
Измените свой script локально, а затем передайте его в ssh, например.
cat commands-to-execute-remotely.sh | ssh blah_server
где commands-to-execute-remotely.sh
выглядит как ваш список выше:
ls some_folder
./someaction.sh
pwd;
Ответ 3
Я вижу два пути:
Сначала вы создаете контрольный сокет следующим образом:
ssh -oControlMaster=yes -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip>
и запустите свои команды
ssh -oControlMaster=no -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip> -t <yourcommand>
Таким образом вы можете написать команду ssh без фактического повторного подключения к серверу.
Вторым было бы динамическое создание script, scp
и его запуск.
Ответ 4
Чтобы соответствовать вашему образцу кода, вы можете обернуть свои команды внутри одного или двух qoutes. Например
ssh blah_server "
ls
pwd
"
Ответ 5
Это также можно сделать следующим образом.
Поместите свои команды в script, назовите его command-inc.sh
#!/bin/bash
ls some_folder
./someaction.sh
pwd
Сохраните файл
Теперь запустите его на удаленном сервере.
ssh [email protected] 'bash -s' < /path/to/commands-inc.sh
Мне никогда не приходило в голову.
Ответ 6
Поместите все команды на script, и его можно запустить как
ssh <remote-user>@<remote-host> "bash -s" <./remote-commands.sh
Ответ 7
SSH и выполните несколько команд в Bash.
Разделяйте команды с точкой с запятой внутри строки, переданной в эхо, все переданные в команду ssh. Например:
echo "df -k;uname -a" | ssh 192.168.79.134
Pseudo-terminal will not be allocated because stdin is not a terminal.
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 18274628 2546476 14799848 15% /
tmpfs 183620 72 183548 1% /dev/shm
/dev/sda1 297485 39074 243051 14% /boot
Linux newserv 2.6.32-431.el6.x86_64 #1 SMP Sun Nov 10 22:19:54 EST 2013 x86_64 x86_64 x86_64 GNU/Linux
Ответ 8
Мысль:
Оберните свои длинные команды в bash script, scp
на конечный сервер, выполните его с помощью ssh
и добавьте команду delete-self в конце script.
Ответ 9
Это хорошо работает для создания скриптов, так как вам не нужно включать другие файлы:
#!/bin/bash
ssh <my_user>@<my_host> "bash -s" << EOF
# here you just type all your commmands, as you can see, i.e.
touch /tmp/test1;
touch /tmp/test2;
touch /tmp/test3;
EOF
Ответ 10
Для тех, кто наткнулся на меня, как на меня, я добился успеха в том, что вы избегали точки с запятой и новой строки:
Первый шаг: точка с запятой. Таким образом, мы не нарушаем команду ssh:
ssh <host> echo test\;ls
^ backslash!
Перечислил удаленный хост/домашний каталог (зарегистрированный как root), тогда как
ssh <host> echo test;ls
^ NO backslash
отображает текущий рабочий каталог.
Следующий шаг: разрыв строки:
v another backslash!
ssh <host> echo test\;\
ls
Это снова отобразило удаленный рабочий каталог - улучшенное форматирование:
ssh <host>\
echo test\;\
ls
Если действительно лучше, чем здесь, документ или цитаты вокруг ломаных строк - ну, не мне решать...
(Используя bash, Ubuntu 14.04 LTS.)
Ответ 11
Самый простой способ настроить вашу систему на использование одиночных сеансов ssh по умолчанию с мультиплексированием.
Это можно сделать, создав папку для сокетов:
mkdir ~/.ssh/controlmasters
И затем добавив следующее в вашу конфигурацию .ssh:
Host *
ControlMaster auto
ControlPath ~/.ssh/controlmasters/%[email protected]%h:%p.socket
ControlMaster auto
ControlPersist 10m
Теперь вам не нужно изменять какой-либо код. Это позволяет многократные вызовы ssh и scp без создания нескольких сеансов, что полезно, когда требуется дополнительное взаимодействие между локальными и удаленными компьютерами.
Спасибо @terminus answer, http://www.cyberciti.biz/faq/linux-unix-osx-bsd-ssh-multiplexing-to-speed-up-ssh-connections/ и https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing.
Ответ 12
Опубликованные ответы с использованием многострочных строк и нескольких сценариев bash не работали для меня.
- Длинные многострочные строки трудно поддерживать.
- Отдельные bash скрипты не поддерживают локальные переменные.
Вот функциональный способ ssh и запускать несколько команд, сохраняя локальный контекст.
LOCAL_VARIABLE=test
run_remote() {
echo "$LOCAL_VARIABLE"
ls some_folder;
./someaction.sh 'some params'
./some_other_action 'other params'
}
ssh otherhost "$(set); run_remote"