Mam plik tekstowy na mojej maszynie lokalnej, który jest generowany przez codzienny skrypt Pythona uruchamiany w cronie.
Chciałbym dodać trochę kodu, aby ten plik był bezpiecznie przesyłany na mój serwer przez SSH.
python
ssh
automation
scp
Alok
źródło
źródło
Odpowiedzi:
Możesz wywołać
scp
polecenie bash (kopiuje pliki przez SSH ) za pomocąsubprocess.run
:Jeśli tworzysz plik, który chcesz wysłać w tym samym programie w języku Python, będziesz chciał wywołać
subprocess.run
polecenie pozawith
blokiem, którego używasz do otwarcia pliku (lub.close()
najpierw wywołaj plik, jeśli nie używaszwith
block), więc wiesz, że jest on opróżniany na dysk z Pythona.Musisz wcześniej wygenerować (na maszynie źródłowej) i zainstalować (na maszynie docelowej) klucz ssh, aby scp został automatycznie uwierzytelniony za pomocą twojego publicznego klucza ssh (innymi słowy, aby twój skrypt nie pytał o hasło) .
źródło
subprocess.check_call(['scp', srcfile, dest])
może być używany od Pythona 2.5 zamiastrc = Popen(..).wait(); if rc != 0: raise ..
Aby to zrobić w Pythonie (tj. Nie owijając scp przez subprocess.Popen lub podobną) z biblioteką Paramiko , zrobiłbyś coś takiego:
(Prawdopodobnie chciałbyś poradzić sobie z nieznanymi hostami, błędami, utworzeniem wszelkich niezbędnych katalogów i tak dalej).
źródło
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
po utworzeniu wystąpieniassh
.Prawdopodobnie użyłbyś modułu podprocesu . Coś takiego:
Gdzie
destination
prawdopodobnie jest formauser@remotehost:remotepath
. Podziękowania dla @Charles Duffy za wskazanie słabości mojej pierwotnej odpowiedzi, która użyła pojedynczego argumentu ciągu do określenia operacji scpshell=True
- która nie obsługuje białych znaków w ścieżkach.Dokumentacja modułu zawiera przykłady sprawdzania błędów, które możesz chcieć wykonać w połączeniu z tą operacją.
Upewnij się, że skonfigurowano odpowiednie poświadczenia, aby można było wykonać nienadzorowany, bezhasłowy scp między komputerami . Jest już pytanie o przepełnienie stosu .
źródło
subprocess.check_call(['scp', myfile, destination])
może być używany zamiast tego od Pythona 2.5 (2006)Istnieje kilka różnych sposobów podejścia do problemu:
Każde podejście ma swoje dziwactwa. Będziesz musiał skonfigurować klucze SSH, aby włączyć logowanie bez hasła, jeśli pakujesz polecenia systemowe, takie jak „ssh”, „scp” lub „rsync”. Możesz osadzić hasło w skrypcie za pomocą Paramiko lub innej biblioteki, ale brak dokumentacji może być frustrujący, szczególnie jeśli nie znasz podstaw połączenia SSH (np. - wymiana kluczy, agenci itp.). Prawdopodobnie jest oczywiste, że klucze SSH są prawie zawsze lepszym pomysłem niż hasła do tego rodzaju rzeczy.
UWAGA: trudno jest pokonać rsync, jeśli planujesz przesyłać pliki przez SSH, zwłaszcza jeśli alternatywą jest zwykły stary scp.
Użyłem Paramiko z zamiarem zastąpienia wywołań systemowych, ale wróciłem do opakowanych poleceń ze względu na ich łatwość użycia i natychmiastową znajomość. Możesz być inny. Dałem Conch raz jeszcze jakiś czas temu, ale nie przemówiło to do mnie.
Jeśli zdecydujesz się na ścieżkę wywołań systemowych, Python oferuje tablicę opcji, takich jak os.system lub moduły commands / subprocess. Wybrałbym moduł podprocesu, jeśli używasz wersji 2.4+.
źródło
Napotkano ten sam problem, ale zamiast „hakowania” lub emulacji wiersza poleceń:
Znalazłem tę odpowiedź tutaj .
źródło
Możesz zrobić coś takiego, aby obsłużyć również sprawdzanie klucza hosta
źródło
fabric
może zostać użyty do przesłania plików vis ssh:źródło
Możesz użyć pakietu wasala, który jest dokładnie do tego przeznaczony.
Wszystko, czego potrzebujesz, to zainstalować wasala i zrobić
Ponadto zapisze ci dane uwierzytelniające i nie musisz ich wpisywać wielokrotnie.
źródło
Użyłem sshfs do zamontowania zdalnego katalogu przez ssh i shutil do skopiowania plików:
Następnie w Pythonie:
Ta metoda ma tę zaletę, że możesz przesyłać strumieniowo dane, jeśli generujesz dane zamiast buforować lokalnie i wysyłać pojedynczy duży plik.
źródło
Spróbuj tego, jeśli nie chcesz używać certyfikatów SSL:
źródło
Korzystanie z zewnętrznego zasobu paramiko;
źródło
Wywołanie
scp
polecenia za pośrednictwem podprocesu nie pozwala na otrzymanie raportu postępu wewnątrz skryptu.pexpect
można użyć do wyodrębnienia tych informacji:Zobacz plik kopii Pythona w sieci lokalnej (linux -> linux)
źródło
Bardzo proste podejście jest następujące:
Żadna biblioteka Pythona nie jest wymagana (tylko system operacyjny) i działa, jednak użycie tej metody wymaga zainstalowania innego klienta ssh. Może to spowodować niepożądane zachowanie, jeśli zostanie uruchomione w innym systemie.
źródło
Trochę hacky, ale poniższe powinny działać :)
źródło