'''''
上傳/下載 文件 ( 電腦 <-> Raspberry pi )
電腦對 Rpi 發送 SSH command
'''''
#-*- coding:utf-8 -*-
import os
import sys
import paramiko
# 須安裝 parmiko 庫
# pip install paramiko
class mySSH(object):
def __init__(self,hostname,port,username,password):
self.ssh = paramiko.SSHClient() # 創建 SSH 物件
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.sftp_T = paramiko.Transport((hostname,port)) #建立sftp加密連線
self.hostname = hostname
self.port = port
self.username = username
self.password = password
# == 單行指令 ==
def send(self,command):
try:
'''''
ssh.exec_command(comment) #執行命令並獲取命令結果
stdin為輸入的命令
stdout為命令返回的結果
stderr為命令錯誤時返回的結果'''''
print("發送 comment = '%s'"%command)
stdin, stdout, stderr = self.ssh.exec_command(command)
res ,err = stdout.read(), stderr.read()
result = res if res else err
return str(result)
except Exception as msg:
print(str(msg))
# == 多行指令 ==
def send_muti(self,command):
try:
'''''
ssh.exec_command(comment) #執行命令並獲取命令結果
stdin為輸入的命令
stdout為命令返回的結果
stderr為命令錯誤時返回的結果 '''''
for i in command:
print("發送 comment = '%s'"%i)
stdin, stdout, stderr = self.ssh.exec_command(i)
res ,err = stdout.read(), stderr.read()
result = res if res else err
print(result)
return str(result)
except Exception as msg:
print(str(msg))
# == Raspberry 重啟 ==
def reBoot(self):
self.ssh.connect(hostname=self.hostname, port=self.port, username=self.username, password=self.password)
command = 'sudo reboot'
result = self.send(command)
self.ssh.close() #關閉連接
# == 自 Raspberry 下載文件 ==
def sftpGet(self,FILEPATH,PCPATH):
try:
username = 'root'
password = 'sftp root 帳戶的密碼(可由sudo passwd root進行設置)'
self.sftp_T.connect(username=username,password=password) #建立加密連線
self.sftp = paramiko.SFTPClient.from_transport(self.sftp_T) #建立一個sftp客戶端
#Copy a remote file (remotepath) from the SFTP server to the local host
self.sftp.get(FILEPATH,PCPATH)
self.sftp_T.close()
print("自 ", FILEPATH,, " 下載至 ",PCPATH, " 完成")
except Exception as msg:
print(str(msg))
# == 上傳文件至 Raspberry ==
def sftpUpLoad(self,FILEPATH,PCPATH):
try:
username = 'root'
password = 'sftp root 帳戶的密碼(可由sudo passwd root進行設置)'
self.sftp_T.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(self.sftp_T)
sftp.put(PCPATH, FILEPATH)
self.sftp_T.close()
print(PCPATH, " 上傳至 ",FILEPATH, " 完成")
except Exception as msg:
print(str(msg))
if __name__=="__main__":
hostname = 'Raspberry IP位址'
port = Raspberry SSH 端口(若你沒特別更改過的話就輸入22)
username = 'pi'
password = '登入 SSH 的密碼'
# 建立物件
Rpi = mySSH(hostname, port, username, password)
# 以下請依自己想測試的 method 進行選用
# ==樹梅派重開機==
Rpi.reBoot()
# 發送單筆 command (記得開頭要 connect , 結尾要 close )
Rpi.ssh.connect(hostname=hostname, port=port, username=username, password=password)
Rpi.send('ls')
Rpi.ssh.close()
# 發送多筆 command (記得開頭要 connect , 結尾要 close )
Rpi.ssh.connect(hostname=hostname, port=port, username=username, password=password)
Rpi.send_muti(['sudo su','ls'])
Rpi.ssh.close()
# ==從 Rpi 的路徑下載文件至電腦==
FILEPATH = '/home/pi/python_program/log_EqLineNotify.txt' #注意須完整指定路徑以及檔名
PCPATH = 'log_EqLineNotify.txt' #注意須完整指定路徑以及檔名(此種寫法會把文件下載到與此.py檔相同路徑下)
Rpi.sftpGet(FILEPATH ,PCPATH)
# ==上傳文件==
FILEPATH = '/etc/testfile.txt'
FILEPATH_PCPATH = r"D:\USER\Desktop\testfile.txt" #注意須完整指定路徑以及檔名(亦可指定路徑),寫法如左
Rpi.sftpUpLoad(FILEPATH,FILEPATH_PCPATH)
->
Sftp 上傳/下載部分,如何設置 root 帳戶請見下篇文章(很多資料夾須設定 root 帳戶才有辦法上傳文件)
一起學 Python 118 : 使用 Python 藉由 sftp 上傳文件至 Rapsberry pi 開啟 root 權限
有關於使用 python 從 Raspberry sftp 上傳以及下載文件可參考以下
Python + Paramiko实现sftp文件上传下载
Python黑帽子——通过Paramiko使用SSH
系統運維工程師的法寶:python paramiko
python模块paramiko与ssh