python基礎5-模塊定義、導入方法、import本質、time和datetime、random、os、sys、shutil、shelve、xml、ConfigParser、hashlib、re

1、 定義

模塊的定義:用來從邏輯上組織python代碼(變量、函數、類、邏輯:實現一個功能),本質上就是.py結尾的python文件(文件名:test.py,對應的模塊名:test)

包的定義:用來從邏輯上組織模塊,本質就是一個目錄(文件夾),必須帶有一個_ _ init _ _().py的文件

2、使用方法(導入方法)

import module_name
import module1_name, module2_name
from module_name import * # 不建議使用
from module_name import logger as log
from . import test # 從當前目錄下導入test,用在導入包下的模塊,寫在__init__.py文件中

3、import的本質

就是把python文件解釋一遍

import module_name	--> modle_name = all_code
from module_name import name	-->	進入module_name文件找到name

導入包的本質:就是解釋包下面的_ _ init _ _.py文件
要想導入包中的文件需要在init中導入模塊即可

這裏存在一個問題就是,模塊和要導入模塊的文件不在同一個目錄下該怎麼辦呢?看下面怎麼解決這個問題

import sys,os
print(sys.path) # 導入模塊時,是在這個列表中的路徑中查找我們要導入的模塊的
os.path.abspath(__file__) # 獲得當前文件的絕對路徑
os.path.dirname(os.path.abspath(__file__)) # 獲取上一層的絕對路徑
sys.path.append(os.path.dirname(os.path.abspath(__file__))) # 加入列表

上面的方法,我們就可以找到需要導入的模塊的位置

4、導入優化

from module import test # 相比於import module速度更快 

5、模塊的分類

a.標準庫
b.開源模塊
c.自定義模塊

自定義模塊和開源模塊的使用參考: http://www.cnblogs.com/wupeiqi/articles/4963027.html

6、內置模塊

time和datetime模塊

在python中,通常有這幾種方式來表示時間:
a.時間戳
時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。用time.time()來獲得這個偏移量,返回的是float類型,單位是秒。
注:1970年是unix誕生年

xue@xue-MacBookAir:~$ python3
Python 3.5.2 (default, Oct  8 2019, 13:06:37) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.time()
1577024037.3293345
>>> 1577024037.3293345/3600/24/365
50.0071041771098
>>> 1970+50
2020
>>> 

b.格式化的時間字符串

c.元組(struct_time)共九個元素
UTC(Coordinated Universal Time)即格林威治天文時間,世界標準時間。在中國爲UTC+8(東八區,全球24個時區),比標準時間早8小時。DST(Daylight Saving Time)即夏令時。

>>> import time
>>> time.localtime()
time.struct_time(tm_year=2019, tm_mon=12, tm_mday=22, tm_hour=22, tm_min=24, tm_sec=23, tm_wday=6, tm_yday=356, tm_isdst=0) 

tm_wday:一個星期中的第幾天,tm_yday:一年中的第幾天,tm_isdst:是不是夏令時

time.timezone # 當地時間和世界標準時間的差值,單位秒
time.gmtime() # 無參時,是把本地的時間傳入,轉換成struct_time,返回值是0區的時間
time.localtime() # 無參時,傳入的是本地時間,轉換成struct_time,返回值是本地的時間
	x = time.localtime()
	x.tm_year
time.mktime(struct_time) # struct_time轉換成時間戳
time.strftime(format, struct_time) # struct_time轉換成格式化的時間字符串
	time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
time.strptime(str, format) # 格式化的時間字符串轉換成struct_time
	time.strftime('2019-12-22 23:12:32', "%Y-%m-%d %H:%M:%S")

time.asctime() # struct_time--->str
time.ctime() # timestamp--->str

在這裏插入圖片描述
在這裏插入圖片描述

import datetime
datetime.datetime.now() # 獲取當前的時間
datetime.datetime.now()+datetime.timedelta(3) # 當天時間+3天
datetime.datetime.now()+datetime.timedelta(-3) # 當天時間-3天
datetime.datetime.now()+datetime.timedelta(hours=3) # 當天時間+3h
datetime.datetime.now()+datetime.timedelta(hours=-3) # 當天時間-3h
datetime.datetime.now()+datetime.timedelta(minutes=3) # 當天時間+3分鐘

c_time = datetime.datetime.now()
c_time.replace(hour=3, minute=30) # 時間的替換

random模塊

import random
random.random() # [0, 1)之間的一個隨機浮點數
random.randint(1, 3) # [1, 3]之間的一個隨機整數
random.uniform(1, 3) # (1, 3)之間的隨機浮點數
random.randrange(1, 10, 2) # [1, 10)之間的一個隨機整數,步數爲2,步數不寫,默認爲1
random.choice()
	random.choice("helloworld")
	random.choice(["1","2","3","4","6","8","9"])
	random.choice(("1","2","3","4","6","8","9"))
random.sample()
	random.sample("hello") # 從前面的序列中,隨機的取兩位返回
	random.shuffle(items) # 打亂順序

實際應用:

#隨機選取0到100間的偶數
random.randrange(0, 100, 2) # 4
	
#隨機浮點數
random.random() #0.2784394798375937597
random.uniform(1, 10) # 9.435457568567835

# 隨機字符
random.choice('asdsfdeerdgs') # f

#多個字符中選取特定數量的字符
random.sample('asdfghjkl', 3) # ['d', 'g', 'h']

#隨機選取字符串
random.choice(['apple', 'pear', 'banana', 'lemon']) # apple

#洗牌
items = [1,2,3,4,5,6,7,8]
random.shuffle(items)

隨機驗證碼的功能

# Author: Mr.Xue
# 2019.10.25
	
import random
	
checkcode = ''
	
for i in range(4):
	tmp = random.randint(0,1)
	if tmp == 1:
		tmp2 = chr(random.randint(65, 90)) # ['A', 'Z']
		checkcode += tmp2
	else:
		tmp2 = random.randint(0, 9)	
		checkcode += str(tmp2)
print(checkcode)	

os模塊

提供對操作系統進行調用的接口

os.getcwd() # 獲取當前的工作目錄,返回str
os.chdir("dirname") # 切換目錄
os.curdir # 返回當前目錄
os.pardir # 返回上一級目錄
os.makedirs('dirname1/dirname2/dirname3') # 遞歸創建多級目錄
os.removedirs('dirname1') # 若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,也刪除,以此類推
os.mkdir('dirname') # 生成單級目錄
os.rmdir('dirname') # 刪除單級目錄,若目錄不爲空則無法刪除,報錯
os.listdir('dirname') # 列出指定目錄下的所有文件和子目錄,包括隱藏文件,並以列表形式打印
os.remove() # 刪除一個文件
os.rename('oldname', 'newname') # 重命名文件/目錄
os.stat('path/filename') # 獲取文件/目錄信息
os.sep # 輸出操作系統特定的路徑分隔符,win下爲"\\",linux下爲"/"
os.linesep # 輸出當前平臺使用的行終止符,win下爲"\r\n",linux下爲"\n"
os.pathsep # 輸出用於分割文件路徑的字符串,win下爲";",linux下爲":"
os.environ # 獲取系統環境變量,返回一個字典類型
os.name # 輸出字符串指示當前使用平臺,win下爲'nt',linux下爲'posix'
os.system("bash command") # 執行shell命令
os.path.abspath(path) # 返回path的絕對路徑
os.path.split(path) # 將path分割成目錄和文件名,返回一個元組
os.path.dirname(path) # 返回目錄,即文件所在的路徑
os.path.basename(path) # 返回path最後的文件名,如果path以'/'或'\'結尾,則返回空值
os.path.exists(path) # 如果path存在則返回True,否則返回False
os.path.isabs(path) # 如果path是絕對路徑,返回True,否則返回False
os.path.isfile(path) # 如果path是一個存在的文件,則返回True,否則返回False
os.path.isdir(path) # 如果path是一個存在的目錄,則返回True,否則返回False
os.path.join(path1[, path2[, ...]]) # 將多個路徑組合後返回
	os.path.join(r'C:', r'\a.txt')
os.path.getatime(path) # 返回path所指向的文件或目錄的最後存取時間
os.path.getmtime(path) # 返回path所指向的文件或目錄的最後修改時間

sys模塊

sys.argv # 命令行參數List,第一個元素是程序本身的路徑
	# test.py
	import sys
	print(sys.argv)

	python3 test.py 1 2 3 4
		
sys.exit(n) # 退出程序,正常退出是exit(0)
sys.version # 獲取python解釋程序的版本信息
sys.maxint # 最大的Int值
sys.path # 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
sys.platform # 返回操作系統平臺名稱
sys.stdout.write('please:')
val = sys.stdin.readline()[:-1]

shutil模塊

高級的文件、文件夾、壓縮包 處理模塊

shutil.copyfileobj(fsrc, fdst[, length]) # 把文件內容拷貝到另一個文件中,可以部分內容
	# 源碼如下
	def copyfileobj(fsrc, fdst, length=16*1024):
	"""copy data from file-like object fsrc to file-like object fdst"""
	while 1:
		buf = fsrc.read(length)
		if not buf:
			break
		fdst.write(buf)
	
	# example
	import shutil
	f1 = open("本節筆記", encoding="utf-8")
	f2 = open("筆記2", "w", encoding="utf-8")
	shutil.copyfileobj(f1, f2)
shutil.copyfile(src, dst) # 拷貝文件
	# 直接傳入文件名,就可以實現copy
	shutil.copyfile("筆記1", "筆記2")
shutil.copymode(src, dst) # 僅拷貝權限,內容、組、 均不變
shutil.copystat(src, dst) # 拷貝狀態的信息,包括:mode bits, atime, mtime, flags
shutil.copy(src, dst) # 拷貝文件和權限
shutil.copy2(src, dst) # 拷貝文件和狀態信息
shutil.copytree(src, dst, symlink=False, ignore=None) # 遞歸的去拷貝文件目錄和文件
shutil.rmtree(dst) # 刪除目錄
shutil.move(src, dst) # 遞歸的去移到文件
"""
創建壓縮包並返回文件路徑,例如:zip、tar
base_name: 壓縮包的文件名,也可以是壓縮包的路徑,只是文件名時,則保存至當前目錄,否則保存至指定路徑,如:www ---> 保存至當前路徑;如:/User/xue/www  ---> 保存至/User/xue
format: 壓縮包種類,如:zip, tar
root_dir: 要壓縮的文件夾路徑(默認當前目錄)
owner: 用戶,默認當前用戶
group: 組,默認當前組
logger: 用於記錄日誌,通常是logging.Logger對象
"""
shutil.make_archive(base_name, format, ...)

# example:
# 將/Users/xue/Downloads/test 下的文件打包放置當前程序目錄
import shutil
ret = shutil.make_archive("www", "gztar", root_dir="/Users/xue/Downloads/test")

# 將/Users/xue/Downloads/test 下的文件打包放置/Users/xue/目錄
import shutil
ret = shutil.make_archive("/Users/xue/www", "gztar",root_dir="/Users/xue/Downloads/test")

shutil對壓縮包的處理是調用ZipFile和TarFile兩個模塊來處理的,下面來詳細看看這兩個模塊

import zipfile

# 壓縮,單獨一個一個壓縮文件
z = zipfile.ZipFile('day5.zip', 'w')
z.write('a.log') # a.log是當前目錄下的一個文件
z.write('data.data')
z.close()

# 解壓
z = zipfile.ZipFile('day5.zip', 'r')
z.extractall()
z.close()
import tarfile
	
# 壓縮
tar = tarfile.open('your.tar', 'w')
tar.add("/Users/xue/bbs/bbs2.zip", arcname="bbs2.zip")
tar.add("/Users/xue/bbs/cmdb.zip", arcname="cmdb.zip")
tar.close()
	
# 解壓
tar = zipfile.ZipFile('day5.zip', 'r')
tar.extractall() # 可設置解壓地址
tar.close()

json & pickle 模塊

用於序列化的兩個模塊,解決了不同平臺不同語言之間的數據交換,pickle相比於json,能夠處理更復雜的數據類型

json: 用於字符串和puyhon數據類型進行轉換
pickle: 用於python特有的類型和python的數據類型進行轉換

Json模塊提供了四個功能:dumps, dump, loads, load
pickle模塊提供了四個功能:dumps, dump, loads, load

import pickle
	
data={'k1': 123, 'k2': 'hello'}
	
p_str = pickle.dumps(data)
print(p_str)

with open('D:/result.pk', 'w')  as fp:
	pickle.dump(data, fp)

shelve模塊

是一個簡單的k, v將內存數據通過文件持久化的模塊,可以持久化任何pickle可支持的python數據格式

import shelve
	
d = shelve.open('shelve_test') # 打開一個文件
	
class Test(object):
	def __init__(self, n):
		self.n = n
t = Test(123)
t2 = Test(123334)
	
name = ['bob', 'xue', 'rain']
# 寫入
d["test"] = name # 持久化列表
d["t1"] = t # 持久化類
d["t2"] = t2
	
# 讀出
d.get("test")
d.get("t")
	
d.close()

xml處理模塊

xml是實現不同語言或程序之間進行數據交換的協議,跟json差不多,在json還沒出來的時候,大家用的就是xml,xml格式如下:

<?xml version="1.0" encoding="utf-8" ?>
<data>
	<a name="a1">
		<to>Tove</to>
		<from updated="yes">hello</from>
		<heading>Reminder</heading>
		<body>Don't forget me this weekend!</body>
	</a>
	<a name="a2">
		<to>bbb</to>
		<from updated="yes">hello</from>
		<heading>Reminder</heading>
		<body>Don't forget me this weekend!</body>
	</a>
</data>

遍歷xml、修改、刪除

# Author: Mr.Xue
# 2019.10.27

import xml.etree.ElementTree as ET
	
tree = ET.parse('xmltree.xml')
root = tree.getroot()
print(root.tag)
	
## 遍歷xml文檔
#for child in root:
	#print(child.tag, child.attrib)
	#for i in child:
		#print(i.tag, i.text)
			
## 只遍歷from節點
#for node in root.iter('from'):
	#print(node.tag, node.text)		
	
## 修改
#for node in root.iter("from"):
	#new_from = 'hello' # 字符串變量new_from
	#node.text = new_from # 賦值,修改顯示信息
	#node.set("updated", 'yes') # 加了個屬性
#tree.write('xmltree.xml')	
	
# 刪除
for a in root.findall('a'):
	to = a.find('to').text
	if to == 'bbb':
		root.remove(a)
tree.write('xmltree2.xml')		

自己創建xml文件

# Author: Mr.Xue
# 2019.10.27

import xml.etree.ElementTree as ET
	
new_xml = ET.Element("name_list")
name = ET.SubElement(new_xml, 'name', attrib={"enrolled": 'yes'})
age = ET.SubElement(name, 'age', attrib={"checked": 'no'})
sex = ET.SubElement(name, 'sex')
age.text = '33'
	
name2 = ET.SubElement(new_xml, 'name', attrib={'enrolled': 'no'})
age = ET.SubElement(name2, 'age')
age.text = '18'
	
et = ET.ElementTree(new_xml) # 生成文檔對象
et.write('test.xml', encoding='utf-8', xml_declaration=True)
	
ET.dump(new_xml) # 打印生成的格式

result:

<?xml version='1.0' encoding='utf-8'?>
<name_list>
	<name enrolled="yes">
		<age checked="no">33</age>
		<sex />
	</name>
	<name enrolled="no">
		<age>18</age>
	</name>
</name_list>

PyYAML模塊

Python也可以很容易的處理ymal文檔格式,只不過需要安裝一個模塊,參考文檔:http://pyyaml.org/wiki/PyYAMLDocumentation

ConfigParser模塊

用於生成和修改常見配置文檔,當前模塊的名稱在python3.x版本中變更爲configparser,常見文檔格式如下:

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
	
[bitbucket.org]
User = hg
	
[topsecret.server.com]
Port = 50022
ForwardX11 = no

怎麼用python生成這樣一個文件呢?

# Author: Mr.Xue
# 2019.10.27
	
import configparser
	
config = configparser.ConfigParser()
	
config["DEFAULT"] = {'ServerAliveInterval': '45',
	'Compression': 'yes',
	'CompressionLevel': '9'}
		
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'

config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'
topsecret["ForwardX11"] = 'no'

config["DEFAULT"]["ForwardX11"] = 'yes'
	
with open('example.ini', 'w') as configfile:
	config.write(configfile)

讀、改、刪

# Author: Mr.Xue
# 2019.10.27
	
import configparser
	
conf = configparser.ConfigParser()
	
conf.read('example.ini')
	
#print(conf.sections())
#print(conf['bitbucket.org']["User"])
#print(conf.defaults())
	
# modify
sec = conf.remove_section('bitbucket.org')
conf.write(open('example.cfg', 'w'))

hashlib、hmac模塊

hashlib
用於加密的相關操作,3.x裏面hashlib替代了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512, MD5 算法

# Author: Mr.Xue
# 2019.10.27
	
import hashlib
	
m = hashlib.md5()
m.update(b"hello")
print(m.digest()) #2進制格式hash
print(m.hexdigest()) #16進制格式hash
m.update(b"It's me")
#m.update("薩達打".encode(encoding='utf-8'))
print(m.hexdigest())
	
m2 = hashlib.md5()
m2.update(b"helloIt's me")
print(m2.hexdigest())
	
s = hashlib.sha1()
s.update(b"helloIt's me")
print(s.hexdigest())

hmac
散列消息鑑別碼,簡稱HMAC,是一種基於消息鑑別碼MAC(Message Authentication Code)的鑑別機制。使用HMAC時,消息通訊的雙方,通過驗證消息中加入的鑑別密鑰K來鑑別消息的真僞;它內部對我們創建 key 和 value 再進行處理然後再加密

一般用於網絡通信中消息加密,前提是雙方先要約定好key,就像接頭暗號一樣,然後消息發送把用key把消息加密,接收方用key + 消息明文再加密,拿加密後的值 跟 發送者的相對比是否相等,這樣就能驗證消息的真實性,及發送者的合法性了。

import hmac # 主要用於消息加密,速度比較快
#h = hmac.new(b'wueiqi') # key, value
#h.update(b'hellowo')
#h = hmac.new(b"wueiqi", b'hellowo')
h = hmac.new("天王蓋地虎".encode(encoding='utf-8'), '寶塔鎮河妖'.encode(encoding='utf-8'))
print(h.hexdigest())

正則表達式Re模塊

常用正則表達式符號
'.'		默認匹配除\n之外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行
'^'		匹配字符開頭
'$'		匹配字符結尾
'*'		匹配*號前的字符0次或多次,re.findall("ab*", "cabb3abcbbac"),結果爲['abb', 'ab', 'a']
'+'		匹配前一個字符1次或多次,re.findall("ab+", "ab+cd+abb+bba"),結果爲['ab', 'abb']
'?'		匹配?前面的字符1次或0'{m}'	匹配前一個字符m次
'{n,m}'	匹配前一個字符n到m次,re.findall("ab{1,3}", "abbabcabbcbbb"),結果爲['abb', 'ab', 'abb']
'|'		匹配|左或右的字符,re.search('abc|ABC', "ABCBabcCD").group(),結果爲'ABC'
'(...)'	分組匹配,re.search("(abc){2}a(123|456)c","abcabca456c").group(),結果abcabca456c
	
'\A'	只從字符串開頭匹配,如'^',re.search("\Aabc", "alexabc")是匹配不到的
'\Z'	匹配字符結尾,同'$'
'\d'	匹配數字0-9,只匹配一個
'\D'	匹配非數字
'\w'	匹配[A-Za-z0-9]
'\W'	匹配非[A-Za-z0-9]
'\s'	匹配空白字符、\t、\n、\r,re.search("\s+", "ab\tc1\n3").group() 結果爲'\t'
最常用的匹配語法
re.match 從頭開始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到列表中返回
re.splitall 以匹配到的字符當做列表分隔符
re.sub 匹配字符並替換
#example:
xue@xue-MacBookAir:~$ python3
Python 3.5.2 (default, Oct  8 2019, 13:06:37) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.match("^Chen", "ChenRonghua123")
<_sre.SRE_Match object; span=(0, 4), match='Chen'>
	
>>> res = re.match("^Chen", "ChenRonghua123")
>>> res.group()
'Chen'
	
>>> res = re.match("^Chen\d+", "Chen123Ronghua123")
>>> res.group()
'Chen123'
	
>>> re.search("R[a-z]+", "Chen123Ronghua123")
<_sre.SRE_Match object; span=(7, 14), match='Ronghua'>
>>> re.search("R[a-z]+", "Chen123Ronghua123Ronghua###")
<_sre.SRE_Match object; span=(7, 14), match='Ronghua'>
	
>>> re.search("a?", "alex")
<_sre.SRE_Match object; span=(0, 1), match='a'>
>>> re.search("a?", "aalex")
<_sre.SRE_Match object; span=(0, 1), match='a'>
>>> re.search("a?", "lex")
<_sre.SRE_Match object; span=(0, 0), match=''>
	
>>> re.search("[0-9]{3}", "a12l324ex")
<_sre.SRE_Match object; span=(4, 7), match='324'>
>>> re.search("[0-9]{1,3}", "a12l324ex")
<_sre.SRE_Match object; span=(1, 3), match='12'>
	
>>> re.findall("[0-9]{1,3}", "a12l324ex")
['12', '324']
	
>>> re.search("(abc){2}", "a12l324exabcabcabc")
<_sre.SRE_Match object; span=(9, 15), match='abcabc'>
>>> re.search("(abc){2}\|", "a12l324exabcabcabc|")
<_sre.SRE_Match object; span=(12, 19), match='abcabc|'>
	
>>> re.search("\A[0-9]+[a-z]\Z", "123435d")
<_sre.SRE_Match object; span=(0, 7), match='123435d'>
	
分組匹配
>>> re.search("(?P<id>[0-9]+)(?P<name>[A-Za-z]+)", "abcd1234efg567").groupdict()
{'id': '1234', 'name': 'efg'}
	
>>> re.split("[0-9]", "abc123de45gh")
['abc', '', '', 'de', '', 'gh']
>>> re.split("[0-9]+", "abc123de45gh")
['abc', 'de', 'gh']
	
>>> re.sub("[0-9]+", "|", "abc12de3f45GH")
'abc|de|f|GH'
>>> re.sub("[0-9]+", "|", "abc12de3f45GH", count=2)
'abc|de|f45GH'
	
>>> re.search(r"\\\\", r"12343\\5dd")
<_sre.SRE_Match object; span=(5, 7), match='\\\\'>
>>> re.search(r"\\", r"12343\5dd")
<_sre.SRE_Match object; span=(5, 6), match='\\'>

匹配模式:

re.I(re.IGNORECASE): 忽略大小寫
re.I(re.IGNORECASE): 忽略大小寫(括號內是完整寫法,下同)
M(MULTILINE): 多行模式,改變'^''$'的行爲(參見上圖)
S(DOTALL): 點任意匹配模式,改變'.'的行爲

>>> re.search("[a-z]+", "abcdE", flags=re.I)
<_sre.SRE_Match object; span=(0, 5), match='abcdE'>

logging模塊

參考:
https://www.cnblogs.com/alex3714/articles/5161349.html

paramiko模塊

該模塊基於SSH用於連接遠程服務器並執行相關操作

SSHClient
用於連接遠程服務器並執行基本命令

基於用戶名密碼連接:

import paramiko
  
# 創建SSH對象
ssh = paramiko.SSHClient()
# 允許連接不在know_hosts文件中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接服務器
ssh.connect(hostname='c1.salt.com', port=22, username='root', password='123')
  
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 獲取命令結果
res, err = stdout.read(), stderr.read()
s = res if res else err
print(s)
  
# 關閉連接
ssh.close()
# SSHClient 封裝 Transport

import paramiko

transport = paramiko.Transport(('hostname', 22))
transport.connect(username='root', password='123')

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('df')
print stdout.read()

transport.close()

基於公鑰密鑰連接:

import paramiko
 
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
 
# 創建SSH對象
ssh = paramiko.SSHClient()
# 允許連接不在know_hosts文件中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接服務器
ssh.connect(hostname='c1.salt.com', port=22, username='root', pkey=private_key)
 
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 獲取命令結果
result = stdout.read()
 
# 關閉連接
ssh.close()
# SSHClient 封裝 Transport

import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')

transport = paramiko.Transport(('hostname', 22))
transport.connect(username='root', pkey=private_key)

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('df')

transport.close()
#基於私鑰字符串進行連接

import paramiko
from io import StringIO

key_str = """-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAq7gLsqYArAFco02/55IgNg0r7NXOtEM3qXpb/dabJ5Uyky/8
NEHhFiQ7deHIRIuTW5Zb0kD6h6EBbVlUMBmwJrC2oSzySLU1w+ZNfH0PE6W6fans
H80whhuc/YgP+fjiO+VR/gFcqib8Rll5UfYzf5H8uuOnDeIXGCVgyHQSmt8if1+e
7hn1MVO1Lrm9Fco8ABI7dyv8/ZEwoSfh2C9rGYgA58LT1FkBRkOePbHD43xNfAYC
tfLvz6LErMnwdOW4sNMEWWAWv1fsTB35PAm5CazfKzmam9n5IQXhmUNcNvmaZtvP
c4f4g59mdsaWNtNaY96UjOfx83Om86gmdkKcnwIDAQABAoIBAQCnDBGFJuv8aA7A
ZkBLe+GN815JtOyye7lIS1n2I7En3oImoUWNaJEYwwJ8+LmjxMwDCtAkR0XwbvY+
c+nsKPEtkjb3sAu6I148RmwWsGncSRqUaJrljOypaW9dS+GO4Ujjz3/lw1lrxSUh
IqVc0E7kyRW8kP3QCaNBwArYteHreZFFp6XmtKMtXaEA3saJYILxaaXlYkoRi4k8
S2/K8aw3ZMR4tDCOfB4o47JaeiA/e185RK3A+mLn9xTDhTdZqTQpv17/YRPcgmwz
zu30fhVXQT/SuI0sO+bzCO4YGoEwoBX718AWhdLJFoFq1B7k2ZEzXTAtjEXQEWm6
01ndU/jhAasdfasdasdfasdfa3eraszxqwefasdfadasdffsFIfAsjQb4HdkmHuC
OeJrJOd+CYvdEeqJJNnF6AbHyYHIECkj0Qq1kEfLOEsqzd5nDbtkKBte6M1trbjl
HtJ2Yb8w6o/q/6Sbj7wf/cW3LIYEdeVCjScozVcQ9R83ea05J+QOAr4nAoGBAMaq
UzLJfLNWZ5Qosmir2oHStFlZpxspax/ln7DlWLW4wPB4YJalSVovF2Buo8hr8X65
lnPiE41M+G0Z7icEXiFyDBFDCtzx0x/RmaBokLathrFtI81UCx4gQPLaSVNMlvQA
539GsubSrO4LpHRNGg/weZ6EqQOXvHvkUkm2bDDJAoGATytFNxen6GtC0ZT3SRQM
WYfasdf3xbtuykmnluiofasd2sfmjnljkt7khghmghdasSDFGQfgaFoKfaawoYeH
C2XasVUsVviBn8kPSLSVBPX4JUfQmA6h8HsajeVahxN1U9e0nYJ0sYDQFUMTS2t8
RT57+WK/0ONwTWHdu+KnaJECgYEAid/ta8LQC3p82iNAZkpWlGDSD2yb/8rH8NQg
9tjEryFwrbMtfX9qn+8srx06B796U3OjifstjJQNmVI0qNlsJpQK8fPwVxRxbJS/
pMbNICrf3sUa4sZgDOFfkeuSlgACh4cVIozDXlR59Z8Y3CoiW0uObEgvMDIfenAj
98pl3ZkCgYEAj/UCSni0dwX4pnKNPm6LUgiS7QvIgM3H9piyt8aipQuzBi5LUKWw
DlQC4Zb73nHgdREtQYYXTu7p27Bl0Gizz1sW2eSgxFU8eTh+ucfVwOXKAXKU5SeI
+MbuBfUYQ4if2N/BXn47+/ecf3A4KgB37Le5SbLDddwCNxGlBzbpBa0=
-----END RSA PRIVATE KEY-----"""

private_key = paramiko.RSAKey(file_obj=StringIO(key_str))
transport = paramiko.Transport(('10.0.1.40', 22))
transport.connect(username='root', pkey=private_key)

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('df')
result = stdout.read()

transport.close()

print(result)

SFTPClient

用於連接遠程服務器並執行上傳下載

基於用戶名密碼上傳下載

import paramiko
 
transport = paramiko.Transport(('hostname',22))
transport.connect(username='root',password='123')
 
sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至服務器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path', 'local_path')
 
transport.close()

基於公鑰密鑰上傳下載

import paramiko
 
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
 
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='root', pkey=private_key )
 
sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至服務器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path', 'local_path')
 
transport.close()

補充

RSA:非對稱密鑰驗證

  • 公鑰
  • 私鑰

比如說:
10.0.0.31請求去連接10.0.0.41,那麼
私鑰放在31,公鑰放在41

需要先在31上生成鑰匙對,用命令ssh-keygen,默認保存在當前用戶的家目錄下

用more /root/.ssh/id_rsa.pub查看公鑰,拷貝到41去,用vim .ssh/authorized_keys打開需要粘貼的位置
除了這個方法,還可以用以下命令來拷貝公鑰,ssh-copy-id “-p52113 [email protected]

ssh [email protected] -p53112這條命令是Linux中遠程登錄另一臺機器的命令

rwx rwx rwx
421
屬主屬組屬others
可讀可寫可執行

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章