[PYTHON] Paramiko + scp Einführung ~ SSH-Verbindung ~ Dateiübertragung mit SCP

Überblick

  1. Senden und Empfangen von Befehlen über die SSH-Verbindung
  2. Holen Sie sich Dateien mit scp

Ergänzung. (A) PC-seitige paramiko + scp Einführung (B) Untersuchung der Paketabhängigkeit (C) Untersuchen Sie die Version des installierten Pakets (D) Visualisierung von Paketabhängigkeiten

Was du machen willst

  1. Senden und Empfangen von Befehlen über die SSH-Verbindung PC (SSH-Client) --- Befehlsausführung mit ssh (mkdir, tar, ...) -> Ziel (SSH-Host)

  2. Holen Sie sich Dateien mit scp PC (SSH-Client) <--- Datei mit scp abrufen (xxx.tar.gz, ...) ---------- Ziel (SSH-Host)

PC(SSH Client)
Windows 7 (64bit)
Python 3.5.2 - Anaconda 4.2.0 (64-bit)
Ziel(SSH Host)
Es ist nur die IP-Adresse bekannt(Hostname unbekannt))
Sie können sich mit ssh als root anmelden
kann scp

(Die im Prozess und in der Umfrage genannte Site wird als Memorandum zusammengefasst.)

Code

1. Senden und Empfangen von Befehlen über die SSH-Verbindung

Wenn Sie sich bei 192.168.1.100 als root anmelden und ein Verzeichnis namens test erstellen möchten

ssh_mkdir1.py


import paramiko
with paramiko.SSHClient() as ssh:
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname='192.168.1.100', port=22, username='root', password='')
    stdin, stdout, stderr = ssh.exec_command('mkdir test')

Es fühlt sich gut an, kurz zu sein Außerdem ist für ssh.connect () ein Passwort oder ein privater Schlüssel (oder beides) erforderlich.

SSH - Python with paramiko issue - Stack Overflow

You should provide either a password or a private key (or both), otherwise the SSH client does not know how to authenticate with the login data.

Mit Kommentar + α sieht es wie folgt aus.

ssh_mkdir.py


import paramiko

#SSH-Client-Objekt(ssh)machen···
with paramiko.SSHClient() as ssh:

    #Wie Hostname&Ich weiß nicht, wie ich den Schlüssel registrieren soll, also AutoAddPolicy()Behalten
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    #ssh verbinden
    ssh.connect(hostname='192.168.1.100', port=22, username='root', password='')
    
    #Führen Sie mkdir aus
    stdin, stdout, stderr = ssh.exec_command('mkdir test')
    
    #Lesen Sie das Ausführungsergebnis stdout und stderr
    for o in stdout:
        print(o)
    for e in stderr:
        print(e)

2. Holen Sie sich Dateien mit scp

Wenn Sie xxx.tar.gz erhalten möchten

scp.py


import paramiko
import scp

with paramiko.SSHClient() as ssh:
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname='192.168.1.100', port=22, username='root', password='')

    #scp client objekterstellung
    with scp.SCPClient(ssh.get_transport()) as scp:
       #Sie können die Datei erhalten, indem Sie einfach zu scp gelangen
       scp.get('xxx.tar.gz','xxx.tar.gz')

Wenn Sie test.py (ein Skript, das 10 Dateien erstellt) mit scp auf das Ziel kopieren und ausführen

test.py


# -*- coding: utf-8 -*-
for n in range(10):
  with open("test" + str(n), "w+") as f:
     f.write("test" + str(n))

scp2.py


# -*- coding: utf-8 -*-
import paramiko
import scp

with paramiko.SSHClient() as ssh:
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname='192.168.1.100', port=22, username='root', password='')

    stdin, stdout, stderr = ssh.exec_command('mkdir test_dir')
    for o in stdout:
        print(o.strip())

    with scp.SCPClient(ssh.get_transport()) as scp:
       scp.put('test.py','test_dir/test.py')

    stdin, stdout, stderr = ssh.exec_command('cd test_dir;python test.py')
    for o in stdout:
        print(o.strip())

    stdin, stdout, stderr = ssh.exec_command('cd test_dir;ls')
    for o in stdout:
        print(o.strip())

Wenn Sie nicht auf die Verarbeitung mit for o in stdout usw. warten, ls oder Python-Test.Es scheint, dass der py-Teil nicht synchron ist.



 --Scp.put () wird vor dem Erstellen des Ordners ausgeführt
 - Zum Zeitpunkt von sh.exec_command ('cd test_dir; ls') ist python test.py unvollständig und der erwartete Ordner wird nicht angezeigt.

 Da war so etwas

## Endgültige Form
 Ich habe dies wie folgt zusammengeführt.


#### **`get_logs.py`**
```python

# -*- coding: utf-8 -*-
import paramiko
import scp
import pathlib
from datetime import datetime
import sys

log_dir = str(datetime.now().strftime('log_%Y%m%d_%H%M%S'))
log_tar_gz = log_dir + '.tar.gz'

remote_path = log_tar_gz
local_path  = str(pathlib.Path(__file__).resolve().parent.joinpath(log_tar_gz))

collect_log_cmds = [
   'mkdir ' + log_dir, 
   # To Do : log_Schreiben Sie etwas, um Protokolle in dir zu sammeln
   'tar -zcvf ' + log_tar_gz + ' ' + log_dir
]

cleanup_cmds = [
	'rm -r ' + log_dir,
	'rm ' + log_tar_gz
]

def check_result(stdin, stdout, stderr):
    result = True
    for o in stdout:
        if o:
            print("    " + o.strip())
    for e in stderr:
        if e:
            print("    " + e.strip())
            result = False
    return result

def exec_command(ssh, cmds):
    result = True
    for cmd in cmds:
        print("  " + cmd)
        stdin, stdout, stderr = ssh.exec_command(cmd)
        if check_result(stdin, stdout, stderr):
            pass
        else:
            print("ERROR -- " + cmd)
            result = False
    return result

with paramiko.SSHClient() as ssh:
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname='192.168.1.100', port=22, username='root', password='')
    
    print("start -- collect_log")
    if exec_command(ssh,  collect_log_cmds):
        print("done -- collect_log)
    else:
        sys.exit()

    print("start -- scp get " + remote_path)
    with scp.SCPClient(ssh.get_transport()) as scp:
        scp.get(remote_path,local_path)

    if pathlib.Path(local_path).is_file():
        print("done  -- scp get " + local_path)
    else:
        print("ERROR -- scp get " + local_path)
        sys.exit()

    print("start -- cleanup")
    if exec_command(ssh, cleanup_cmds):
        print("done  -- cleanup")
    else:
        print("ERROR -- cleanup")
        sys.exit()

Ergänzung

(A) PC-seitige paramiko + scp Einführung

paramiko 2.2.1 Paketabhängigkeiten

paramiko.png

Paketerfassung

required used .whl
bcrypt(>=3.1.3) bcrypt 3.1.3 bcrypt-3.1.3-cp35-cp35m-win_amd64.whl
pynacl(>=1.0.1) pynacl 1.1.2 PyNaCl-1.1.2-cp35-cp35m-win_amd64.whl
paramiko(2.2.1) paramiko 2.2.1 paramiko-2.2.1-py2.py3-none-any.whl
scp(0.10.2) scp 0.10.2 scp-0.10.2-py2.py3-none-any.whl

――Ich wusste nicht, welche .whl von bcrypt ist, also habe ich mich aufgrund des Fehlers für OK / NG entschieden, als ich etwas eingefügt habe, das nicht zur Umgebung passt (durch Ausprobieren gelöst).

Paketinstallation

--Pip install <Heruntergeladene .whl>

> pip install bcrypt-3.1.3-cp35-cp35m-win_amd64.whl
・ ・ ・
> pip install PyNaCl-1.1.2-cp35-cp35m-win_amd64.whl
・ ・ ・
> pip install paramiko-2.2.1-py2.py3-none-any.whl
・ ・ ・ ・
> pip install scp-0.10.2-py2.py3-none-any.whl
・ ・ ・ ・

(B) Untersuchung der Paketabhängigkeit

> pip install paramiko-2.2.1-py2.py3-none-any.whl
Collecting bcrypt>=3.1.3 (from paramiko==2.2.1)
  Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x02DB4A30>: Failed to establish a new connection: [Errno 11004] getaddrinfo failed',)': /simple/bcrypt/
・ ・ ・
> pip install paramiko-2.2.1-py2.py3-none-any.whl
Requirement already satisfied: bcrypt>=3.1.3 in ・ ・ ・\lib\site-packages (from paramiko==2.2.1)
Requirement already satisfied: cryptography>=1.1 in · · ·\lib\site-packages (from paramiko==2.2.1)
Requirement already satisfied:sechs in ・ ・ ・\lib\site-packages (from pynacl>=1.0.1->paramiko==2.2.1)
Requirement already satisfied: cffi>=1.4.1 in · · ·\lib\site-packages (from pynacl>=1.0.1->paramiko==2.2.1)
Requirement already satisfied: idna>=2.0 in ・ ・ ・\ib\site-packages (from cryptography>=1.1->paramiko==2.2.1)
Requirement already satisfied: setuptools>=11.3 in in ・ ・ ・\lib\site-packages\setuptools-27.2.0-py3.6.egg (from cryptography>=1.1->paramiko==2.2.1)
Requirement already satisfied:pycparser in ・ ・ ・\ib\site-packages (from cffi>=1.4.1->pynacl>=1.0.1->paramiko==2.2.1)
Installing collected packages: pynacl, bcrypt, paramiko

[Was ich später herausgefunden habe] 6 ... .whl ist .zip.

--paramiko-2.2.1-py2.py3-none-convert .whl in .zip und entpacken. --METADATA ist in paramiko-2.2.1.dist-info enthalten.

Wenn Sie also nachforschen möchten, können Sie dies tun.

paramiko-2.2.1.dist-info/METADATA


Metadata-Version: 2.0
Name: paramiko
Version: 2.2.1
・ ・ ・
Requires-Dist: bcrypt (>=3.1.3)
Requires-Dist: cryptography (>=1.1)
Requires-Dist: pynacl (>=1.0.1)
Requires-Dist: pyasn1 (>=0.1.7)
・ ・ ・

(C) Untersuchen Sie die Version des installierten Pakets

> pip freeze
alabaster==0.7.9
anaconda-client==1.6.0
anaconda-navigator==1.5
... weggelassen ...

--setuptools und pycparser kommen nicht mit Pip Freeze heraus, also [erhalten Sie von "version"] 8

ipython


In [1]: import setuptools

In [2]: setuptools.__version__
Out[2]: '27.2.0'

In [3]: import pycparser

In [4]: pycparser.__version__
Out[4]: '2.14'

(D) Visualisierung von Paketabhängigkeiten

paramiko_depend.dot


digraph pramiko {
   scp->paramiko
   paramiko->bcrypt;
   paramiko->pynacl;
   paramiko->pyasn1;
   paramiko->cryptography;
   bcrypt->cffi;
   bcrypt->six;
   cryptography->idna;
   cryptography->setuptools;
   cffi->pycparser;
   scp[label="scp\n(0.10.2)", color = "red"];
   paramiko[label="paramiko\n(2.2.1)", color = "red"];
   bcrypt[label="bcrypt\n(>=3.1.3)", color = "red"];
   pynacl[label="pynacl\n(>=1.0.1)", color = "red"];
   pyasn1[label="pyasn1\n(0.1.9)"];
   cryptography[label="cryptography\n(1.5)"];
   cffi[label="cffi\n(1.7.0)"];
   six[label="six\n(1.10.0)"]
   idna[label="idna\n(2.1)"]
   setuptools[label="setuptools\n(27.2.0)"]
   pycparser[label="pycparser\n(2.14)"]
}
> dot.exe -Tpng paramiko_depend.dot > paramiko_depend.png

Referenz

paramiko 2.2.1 : Python Package Index scp 0.10.2 : Python Package Index Paramiko Release [Paramiko sendet automatisch Befehle und zeichnet Ergebnisse auf - Qiita] 1 SSH - Python with paramiko issue - Stack Overflow [Verwenden von Paramiko zum Streamen von Shell-Skripten zu einem Remote-Host-Qiita] 14 [SFTP / SCP in Python mit paramiko-Librabuc] 10 [Scp im Python-interessanten Inhaltssuchtagebuch] 13 SSH - Python with paramiko issue - Stack Overflow [[Python] Pip und Rad - Qiita] 6 [Visualisieren Sie Python-Paketabhängigkeiten mit graphviz - Qiita] 7 [Die Version des Python-Moduls ist --Drkcore] 8 [Einführung in die DOT-Sprache | Du siehst zu cool aus] 11

Recommended Posts

Paramiko + scp Einführung ~ SSH-Verbindung ~ Dateiübertragung mit SCP
Schnelle Dateiübertragung mit Stoff
Bidirektionale Dateiübertragung in Pythonista 3
Bis zur SSH-Verbindung mit Fabric (MacOS-> CentOS7)
Bearbeiten Sie die Datei des SSH-Verbindungszielservers auf dem Server mit VS-Code
[Hinweis] SSH-Verbindung vom Terminal mit AWS LightSail
Beschreiben Sie das mehrstufige SSH-Ziel in der Konfiguration, melden Sie sich einfach an und kopieren Sie die Datei mit scp