[PYTHON] Introduction à Paramiko + scp ~ Connexion SSH ~ Transfert de fichiers avec SCP

Aperçu

  1. Envoyer et recevoir des commandes depuis la connexion ssh
  2. Obtenez des fichiers avec scp

Supplément. (A) Introduction paramiko côté PC + SCP (B) enquête sur les dépendances du package (C) Examinez la version du package installé (D) Visualisation des dépendances des packages

Chose que tu veux faire

  1. Envoyer et recevoir des commandes depuis la connexion ssh PC (client SSH) --- Exécution de la commande avec ssh (mkdir, tar, ...) -> Cible (hôte SSH)

  2. Obtenez des fichiers avec scp PC (client SSH) <--- Obtenir le fichier avec scp (xxx.tar.gz, ...) ---------- Cible (hôte SSH)

PC(SSH Client)
Windows 7 (64bit)
Python 3.5.2 - Anaconda 4.2.0 (64-bit)
cible(SSH Host)
Seule l'adresse IP est connue(nom d'hôte inconnu))
Vous pouvez vous connecter en tant que root avec ssh
peut scp

(Le site mentionné dans le processus et l'enquête est résumé sous forme de mémorandum)

code

1. Envoyer et recevoir des commandes depuis la connexion ssh

Si vous souhaitez vous connecter à 192.168.1.100 en tant que root et créer un répertoire appelé test

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')

Ça fait du bien d'être court De plus, un mot de passe ou une clé privée (ou les deux) est requis pour ssh.connect ().

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.

Avec comment + α, cela ressemble à ce qui suit.

ssh_mkdir.py


import paramiko

#objet client ssh(ssh)faire···
with paramiko.SSHClient() as ssh:

    #Comment le nom d'hôte&Je ne sais pas comment enregistrer la clé, donc AutoAddPolicy()Garder
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    #connexion ssh
    ssh.connect(hostname='192.168.1.100', port=22, username='root', password='')
    
    #Exécutez mkdir
    stdin, stdout, stderr = ssh.exec_command('mkdir test')
    
    #Lire le résultat de l'exécution stdout et stderr
    for o in stdout:
        print(o)
    for e in stderr:
        print(e)

2. Obtenez des fichiers avec scp

Si vous voulez obtenir xxx.tar.gz

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='')

    #création d'objet client scp
    with scp.SCPClient(ssh.get_transport()) as scp:
       #Vous pouvez obtenir le fichier simplement en accédant à scp
       scp.get('xxx.tar.gz','xxx.tar.gz')

Lors de la copie de test.py (un script qui crée 10 fichiers) sur la cible avec scp et de son exécution

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())

Si vous n'attendez pas le traitement avec for o dans stdout etc., test ls ou python.Il semble que la partie py soit désynchronisée.



 --Scp.put () est exécuté avant la création du dossier
 --Au moment de sh.exec_command ('cd test_dir; ls'), python test.py est incomplet et le dossier attendu n'est pas affiché.

 Il y avait une telle chose

## Forme finale
 J'ai fusionné cela dans ce qui suit.


#### **`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_Écrivez quelque chose pour collecter les journaux dans dir
   '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()

Supplément

(A) Introduction paramiko côté PC + SCP

paramiko 2.2.1 Dépendances des packages

paramiko.png

--Paquets où le cercle rouge de la figure n'a pas été installé

Acquisition de packages

--Accédé [pypi] 3 avec un navigateur et téléchargé .whl

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

――Je ne savais pas quel .whl de bcrypt était, alors j'ai décidé OK / NG en fonction de l'erreur lorsque j'ai mis quelque chose qui ne convenait pas à l'environnement (je l'ai résolu par essais et erreurs).

Installation du package

--Pip install <.whl téléchargé>

> 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) enquête sur les dépendances du package

> 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/
・ ・ ・

--Lorsque paramiko peut être installé, ce sera comme suit.

> pip install paramiko-2.2.1-py2.py3-none-any.whl
Requirement already satisfied: bcrypt>=3.1.3 pouces ・ ・ ・\lib\site-packages (from paramiko==2.2.1)
Requirement already satisfied: cryptography>=1.1 dans ・ ・ ・\lib\site-packages (from paramiko==2.2.1)
Requirement already satisfied:six pouces ・ ・ ・\lib\site-packages (from pynacl>=1.0.1->paramiko==2.2.1)
Requirement already satisfied: cffi>=1.4.1 dans ・ ・ ・\lib\site-packages (from pynacl>=1.0.1->paramiko==2.2.1)
Requirement already satisfied: idna>=2.0 dans ・ ・ ・\ib\site-packages (from cryptography>=1.1->paramiko==2.2.1)
Requirement already satisfied: setuptools>=11.3 pouces dans ・ ・ ・\lib\site-packages\setuptools-27.2.0-py3.6.egg (from cryptography>=1.1->paramiko==2.2.1)
Requirement already satisfied:pycparser dans ・ ・ ・\ib\site-packages (from cffi>=1.4.1->pynacl>=1.0.1->paramiko==2.2.1)
Installing collected packages: pynacl, bcrypt, paramiko

[Ce que j'ai découvert plus tard] 6 ... .whl est .zip.

--paramiko-2.2.1-py2.py3-none-convertit .whl en .zip et décompressez. --METADATA est inclus dans paramiko-2.2.1.dist-info. --Lorsque vous ouvrez METADATA avec un éditeur de texte, il est écrit dans Requirements-Dist.

Donc, si vous voulez enquêter, vous pouvez le faire.

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) Examinez la version du package installé

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

--setuptools et pycparser ne sortent pas avec pip freeze, donc [obtenir à partir de "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) Visualisation des dépendances des packages

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)"]
}

--Platinisé avec Graphviz (Graphviz2.38 \ bin \ dot.exe)

> dot.exe -Tpng paramiko_depend.dot > paramiko_depend.png

référence

paramiko 2.2.1 : Python Package Index scp 0.10.2 : Python Package Index Paramiko Release [Paramiko envoie automatiquement des commandes et enregistre les résultats --Qiita] 1 SSH - Python with paramiko issue - Stack Overflow [Utilisation de Paramiko pour diffuser des scripts shell vers un hôte distant-Qiita] 14 [SFTP / SCP en Python avec paramiko-Librabuc] 10 [Scp dans le journal de recherche de contenu intéressant Python] 13 SSH - Python with paramiko issue - Stack Overflow [[Python] pip et roue - Qiita] 6 [Visualisez les dépendances des packages python avec graphviz - Qiita] 7 [La version du module python est --Drkcore] 8 [Introduction au langage DOT | Vous avez l'air trop cool] 11

Recommended Posts

Introduction à Paramiko + scp ~ Connexion SSH ~ Transfert de fichiers avec SCP
Transfert de fichiers rapide avec tissu
Transfert de fichiers bidirectionnel dans Pythonista 3
Jusqu'à la connexion SSH avec Fabric (MacOS-> CentOS7)
Modifiez le fichier du serveur de destination de la connexion SSH sur le serveur avec VS Code
[Remarque] Connexion ssh depuis le terminal avec AWS LightSail
Décrivez la destination ssh en plusieurs étapes dans la configuration, connectez-vous facilement et copiez le fichier avec scp