Mam maszynę lokalną, która ma wykonać sesję SSH na master
maszynie zdalnej , a następnie kolejną wewnętrzną sesję SSH z master
każdego do każdego zdalnego slaves
, a następnie wykonać 2 polecenia, tj. Usunąć konkretny katalog i odtworzyć go.
Zauważ, że lokalna maszyna ma SSH bez hasła do urządzenia master, a master ma bez hasła hasło do urządzenia slave. Również wszystkie nazwy hostów są znane .ssh/config
z maszyn lokalnych / głównych, a nazwy hostów niewolników znajdują się slaves.txt
lokalnie i stamtąd je czytam.
Więc to, co robię i pracuję, to:
username="ubuntu"
masterHostname="myMaster"
while read line
do
#Remove previous folders and create new ones.
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rm -rf Input Output Partition""
ssh -n $username@$masterHostname "ssh -t -t $username@$line "mkdir -p EC2_WORKSPACE/$project Input Output Partition""
#Update changed files...
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rsync --delete -avzh /EC2_NFS/$project/* EC2_WORKSPACE/$project""
done < slaves.txt
Ten klaster znajduje się na Amazon EC2 i zauważyłem, że przy każdej iteracji powstaje 6 sesji SSH, co powoduje znaczne opóźnienie. Chciałbym połączyć te 3 polecenia w 1, aby uzyskać mniej połączeń SSH. Próbowałem więc połączyć pierwsze 2 polecenia
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rm -rf Input Output Partition && mkdir -p EC2_WORKSPACE/$project Input Output Partition""
Ale to nie działa zgodnie z oczekiwaniami. Wydaje się, że wykonuje pierwszą ( rm -rf Input Output Partition
), a następnie kończy sesję i kontynuuje. Co mogę zrobić?
źródło
-J
opcji, która zdefiniowałaby twojego hosta skoku.Odpowiedzi:
Weź pod uwagę, że
&&
jest to operator logiczny. Czyni nie znaczyć „też uruchomić tę komendę” oznacza „tego polecenia, jeżeli druga udało”.Oznacza to, że jeśli
rm
polecenie się nie powiedzie (co się stanie, jeśli którykolwiek z trzech katalogów nie istnieje), to poleceniemkdir
nie zostanie wykonane. To nie brzmi jak pożądane zachowanie; jeśli katalogi nie istnieją, prawdopodobnie można je utworzyć.Posługiwać się
;
Średnik
;
służy do oddzielania poleceń. Polecenia są uruchamiane sekwencyjnie, czekając na każde z nich przed przejściem do następnego, ale ich sukces lub porażka nie mają na siebie wpływu.Unikaj wewnętrznych cytatów
Cytaty w innych cytatach należy unikać, w przeciwnym razie tworzysz dodatkowy punkt końcowy i punkt początkowy. Twoje polecenie:
Staje się:
Twoje bieżące polecenie, z powodu braku cudzysłowów, powinno wykonywać:
jeśli to się uda:
Zauważysz, że podświetlanie składni pokazuje tutaj całe polecenie na czerwono, co oznacza, że całe polecenie jest ciągiem przekazywanym do ssh. Sprawdź swoją maszynę lokalną; możesz mieć katalogi
Input
Output
iPartition
gdzie to działało.źródło
&
polecenia przyczyny uruchomić int on tła, co oznacza, przyzwyczajenie być czekał do końca przed przejściem do następnego.Zawsze możesz zdefiniować w swoim jumpboxie Multipleksowanie w OpenSSH
Aby to zrobić w
/etc/ssh/ssh_config
:W ten sposób wszelkie kolejne połączenia wykonane z tym samym serwerem w ciągu następnych 30 minut zostaną wykonane ponownie przy użyciu poprzedniego połączenia ssh.
Możesz także zdefiniować go dla maszyny lub grupy maszyn. Z podanego linku.
źródło
/tmp/
.man ssh
,ControlPath
,ControlMaster
iControlPersist
są ważne opcje przekazaćssh
polecenie używając-o
. Może to być bardziej precyzyjny przypadek użycia, skonfiguruj multipleksowanie w pierwszymssh
skrypcie i poddaj go recyklingowi dla innych, ale w przeciwnym razie uniknij obniżenia wydajności. Zastanawiam się, jaki jest punkt odniesienia dla multipleksowania VS nie dla 3 połączeń SSH, biorąc pod uwagę, że „Istnieje również znaczne opóźnienie przy otwieraniu nowego połączenia”Możesz umieścić wszystkie swoje polecenia w osobnym skrypcie na serwerze „głównym”.
Skrypt główny
Następnie w skrypcie ssh nazwij to tak: Skrypt SSH
LUB jeśli wszystkie pliki muszą znajdować się na komputerze początkowym, możesz zrobić coś takiego:
skrypt1
skrypt2
skrypt ssh
źródło
Jakiś czas temu miałem okazję używać gniazd sterujących, tak jak inne odpowiedzi polecają (ta odpowiedź jest zasadniczo połączeniem używania gniazd sterujących takich jak ta odpowiedź i skryptów takich jak ta odpowiedź ).
Przypadek użycia to włamanie:
authorized_keys
użytkownik docelowy był okresowo nadpisywany przez zaplanowane zadanie i chciałem szybko przetestować rzeczy bez przechodzenia przez biurokrację potrzebną do dodania czegoś do tego pliku. Więc ustawiłem pętlę while, która w razie potrzeby dodała klucz do tego pliku, uruchomiłem test i anulowałem pętlę. Byłoby jednak małe okno, w którym zaplanowane zadanie zastąpiłoby plik, a moja pętla nadalsleep
działała. Tak więc ustawienie gniazda kontrolnego na początku pozwoliłoby mojemu skryptowi SSH później bez problemów:Gdzie
setup-ssh.sh
jest:I
.ssh-config
:I
run-test.sh
:Sekwencja wygląda następująco:
setup-ssh.sh
.setup-ssh.sh
busy-loop zapełnia serwery, dopóki wszystkie nie skonfigurują gniazda kontrolnego.hosts
Plik po prostu wymienia jedną hostów serwera w wierszu.${CONFIG_DIR}/scripts/.ssh-config
, chyba że określę ten plik za pomocą-F
, połączenia SSH nie będą go używać. To pozwala mi używać gniazda kontrolnego tylko tam, gdzie potrzebuję ich, używającF
opcji.xargs
do rozłożenia obciążenia na serwery, rozpoczynając nowe zadania natychmiast po ich zakończeniu.źródło