it-swarm.com.ru

Какой самый простой способ использовать ssh и запускать несколько команд в Bash?

У меня уже настроен агент ssh, и я могу запускать команды на внешнем сервере в скрипте Bash, выполняя такие вещи, как:

ssh blah_server "ls; pwd;"

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

Итак, есть ли способ, которым я могу сделать это за один раз, заключенный в скобки или что-то? Я ищу что-то вроде:

ssh blah_server (
   ls some_folder;
   ./someaction.sh;
   pwd;
)

В принципе, я буду рад любому решению, если оно чистое.

Правка

Чтобы прояснить, я говорю об этом как о части большего сценария bash. Другим людям, возможно, потребуется разобраться со сценарием, поэтому я бы хотел сохранить его в чистоте. Я не хочу иметь bash-скрипт с одной строкой, которая выглядит следующим образом:

ssh blah_server "ls some_folder; ./someaction.sh 'some params'; pwd; ./some_other_action 'other params';"

потому что это очень некрасиво и трудно читать.

278
Eli

Как насчет Bash Вот документ :

ssh otherhost << EOF
  ls some_folder; 
  ./someaction.sh 'some params'
  pwd
  ./some_other_action 'other params'
EOF

Чтобы избежать проблем, упомянутых @Globalz в комментариях, возможно, вам удастся (в зависимости от того, что вы делаете на удаленном сайте) заменить первую строку на

ssh otherhost /bin/bash << EOF

Обратите внимание, что вы можете выполнить подстановку переменных в документе Here, но вам, возможно, придется столкнуться с проблемами цитирования. Например, если вы заключите в кавычки «предельную строку» (т. Е. EOF в приведенном выше), то вы не сможете выполнять подстановки переменных. Но без цитирования предельной строки переменные подставляются. Например, если вы определили $NAME выше в своем скрипте Shell, вы можете сделать

ssh otherhost /bin/bash << EOF
touch "/tmp/${NAME}"
EOF

и он создаст файл в месте назначения otherhost с именем того, что вы присвоили $NAME. Другие правила, касающиеся цитирования сценариев оболочки, также применимы, но они слишком сложны, чтобы их здесь приводить.

387
Paul Tomblin

Отредактируйте ваш скрипт локально, затем передайте его в ssh, например,.

cat commands-to-execute-remotely.sh | ssh blah_server

где commands-to-execute-remotely.sh выглядит как ваш список выше:

ls some_folder
./someaction.sh
pwd;
102
bosmacs

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

ssh blah_server "
  ls
  pwd
"
32
Andrei B

Я вижу два пути:

Сначала вы создаете управляющий сокет следующим образом:

 ssh -oControlMaster=yes -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip>

и запускай свои команды

 ssh -oControlMaster=no -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip> -t <yourcommand>

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

Вторым было бы динамически сгенерировать скрипт, scping и запустить.

31
terminus

Это также можно сделать следующим образом . Поместите ваши команды в скрипт, назовем его command-inc.sh

#!/bin/bash
ls some_folder
./someaction.sh
pwd

Сохранить файл

Теперь запустите его на удаленном сервере.

ssh [email protected] 'bash -s' < /path/to/commands-inc.sh

Никогда не подводил для меня.

16
R J

SSH и запуск нескольких команд в Bash.

Отдельные команды с точкой с запятой в строке, передаваемые в echo, передаются в команду 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
arnab

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

ssh <remote-user>@<remote-Host> "bash -s" <./remote-commands.sh
7
Jai Prakash

Для любого, кто споткнулся здесь, как я, - мне удалось избежать точки с запятой и новой строки:

Первый шаг: точка с запятой. Таким образом, мы не нарушаем команду ssh:

ssh <Host> echo test\;ls
                    ^ backslash!

Перечислен удаленный каталог hosts/home (вошел как 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.)

5
Aconcagua

Это хорошо работает для создания сценариев, так как вам не нужно включать другие файлы:

#!/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
4
sjas

Самый простой способ настроить систему на использование одиночных сессий ssh ​​по умолчанию с мультиплексированием.

Это можно сделать, создав папку для сокетов:

mkdir ~/.ssh/controlmasters

А затем добавьте следующее в вашу конфигурацию .ssh:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/controlmasters/%[email protected]%h:%p.socket
    ControlMaster auto
    ControlPersist 10m

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

Благодаря ответу @ конечной станции, http://www.cyberciti.biz/faq/linux-unix-osx-bsd-ssh-multiplexing-to-speed-up-ssh-connections/ и https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing .

2
Jonathan

Отправленные ответы с использованием многострочных строк и нескольких сценариев 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"
2
Michael Petrochuk

Не уверен, что самый чистый для длинных команд, но, конечно, самый простой:

ssh [email protected] "cmd1; cmd2; cmd;3"
0
DimiDak