Jaki jest najczystszy sposób na ssh i uruchamianie wielu poleceń w Bash?

Mam już skonfigurowanego agenta ssh i mogę uruchamiać polecenia na zewnętrznym serwerze w skrypcie Bash robiąc takie rzeczy jak:

ssh blah_server "ls; pwd;"
Naprawdę chciałbym uruchomić wiele długich poleceń na zewnętrznym serwerze. Umieszczenie tych wszystkich pomiędzy cudzysłowami byłoby dość brzydkie i naprawdę wolałbym unikać ssh ' ING wiele razy, aby tego uniknąć.

Więc, czy jest jakiś sposób, żebym mógł to zrobić za jednym razem w nawiasach, czy coś? Szukam czegoś na linie:

ssh blah_server (
   ls some_folder;
   ./someaction.sh;
   pwd;
)
Zasadniczo będę zadowolony z każdego rozwiązania, o ile jest czyste.

Edit

Aby wyjaśnić, mówię o tym, że jest to część większego skryptu bash. Inni ludzie będą musieli zająć się scenariuszem, więc chcę, żeby był czysty. Nie chcę mieć skryptu Basha z jedną linią, która wygląda tak:

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

Ponieważ jest niezwykle brzydka i trudna do odczytania.

 251
Author: codeforester, 2010-12-10

11 answers

A może Bash tutaj dokument :

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

Aby uniknąć problemów wymienionych przez @ Globalz w komentarzach, możesz (w zależności od tego, co robisz na zdalnej stronie) uciec od zastąpienia pierwszej linii przez

ssh otherhost /bin/bash << EOF

Zauważ, że możesz zastąpić zmienną w dokumencie Here, ale możesz mieć do czynienia z kwestiami cytowania. Na przykład, jeśli zacytujesz "limit string" (tj. EOF w powyższym przykładzie), wtedy nie można wykonywać podstawień zmiennych. Ale bez cytując łańcuch ograniczeń, zmienne są zastępowane. Na przykład, jeśli zdefiniowałeś $NAME powyżej w swoim skrypcie powłoki, możesz wykonać

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

I utworzy plik na miejscu docelowym otherhost z nazwą tego, co przypisałeś $NAME. Inne zasady dotyczące cytowania skryptów powłoki również mają zastosowanie, ale są zbyt skomplikowane, aby tutaj wchodzić.

 351
Author: Paul Tomblin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-15 02:14:17

Edytuj skrypt lokalnie, a następnie prześlij go do ssh, np.

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

Gdzie commands-to-execute-remotely.sh wygląda jak twoja lista powyżej:

ls some_folder
./someaction.sh
pwd;
 97
Author: bosmacs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-10 19:00:54

Widzę dwa sposoby:

Najpierw tworzysz Gniazdo sterujące w ten sposób:

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

I uruchom swoje polecenia

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

W ten sposób możesz napisać polecenie ssh bez ponownego łączenia się z serwerem.

Drugim będzie dynamiczne generowanie skryptu, scpi uruchamianie go.

 32
Author: terminus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-16 11:22:43

Aby dopasować przykładowy kod, możesz zawijać polecenia w pojedyncze lub podwójne qutes. Na przykład

ssh blah_server "
  ls
  pwd
"
 29
Author: Andrei B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-27 08:17:51

Można to również zrobić w następujący sposób. Umieść swoje polecenia w skrypcie, nazwijmy go commands-inc.sh

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

Zapisz plik

Teraz uruchom go na zdalnym serwerze.

ssh user@remote 'bash -s' < /path/to/commands-inc.sh
Nigdy nie zawiodłem.
 15
Author: R J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-07 22:03:51

Umieść wszystkie polecenia na skrypcie i może być uruchomiony jak

ssh <remote-user>@<remote-host> "bash -s" <./remote-commands.sh
 8
Author: Jai Prakash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-05 04:50:40

SSH i uruchom wiele poleceń w Bash.

Osobne polecenia ze średnikami w łańcuchu, przekazywane do echo, wszystkie umieszczone w poleceniu ssh. Na przykład:

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
Author: arnab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-07 01:19:01

Dla każdego, kto tu potyka się jak ja-udało mi się uciec od średnika i nowej linii:

Pierwszy krok: średnik. W ten sposób nie łamiemy polecenia ssh:

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

Wypisał katalog zdalny host /Dom (zalogowany jako root), natomiast

ssh <host> echo test;ls
                    ^ NO backslash

Wymieniono bieżący katalog roboczy.

Następny krok: rozbicie linii:

                      v another backslash!
ssh <host> echo test\;\
ls

Ponownie wymieniono zdalny katalog roboczy-ulepszone formatowanie:

ssh <host>\
  echo test\;\
  ls

If really nicer niż tutaj dokument lub cytaty wokół łamanych linii-cóż, nie ja decydować...

(używając Basha, Ubuntu 14.04 LTS.)

 5
Author: Aconcagua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-28 11:33:22

To działa dobrze przy tworzeniu skryptów, ponieważ nie musisz dołączać innych plików:

#!/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
 3
Author: sjas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-26 19:38:59

Najprostszy sposób skonfigurowania systemu do używania pojedynczych sesji ssh domyślnie z multipleksowaniem.

Można to zrobić, tworząc folder dla gniazd:

mkdir ~/.ssh/controlmasters

A następnie dodanie następujących do twojego .konfiguracja ssh:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/controlmasters/%r@%h:%p.socket
    ControlMaster auto
    ControlPersist 10m

Teraz nie musisz modyfikować żadnego kodu. Pozwala to na wiele połączeń do ssh i scp bez tworzenia wielu sesji, co jest przydatne, gdy konieczna jest większa interakcja między lokalnym a zdalnym maszyny.

Dzięki odpowiedzi @terminus, http://www.cyberciti.biz/faq/linux-unix-osx-bsd-ssh-multiplexing-to-speed-up-ssh-connections/ i https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing .

 2
Author: Jonathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-23 08:07:14

Opublikowane odpowiedzi za pomocą ciągów wielowierszowych i wielu skryptów bash nie działały dla mnie.

  • długie ciągi Wielowierszowe są trudne do utrzymania.
  • oddzielne skrypty bash nie utrzymują zmiennych lokalnych.

Oto funkcjonalny sposób na ssh i uruchamianie wielu poleceń przy zachowaniu lokalnego kontekstu.

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"
 1
Author: Michael Petrochuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-04 16:25:12