Black-Gold 5 years ago
parent 246e7cd5e9
commit 1ee76ca2a9

File diff suppressed because it is too large Load Diff

@ -46,6 +46,8 @@ echo -n xxx | openssl md5 # 方法二
echo $RANDOM | md5sum | cut -c 1-8 # 方法一 echo $RANDOM | md5sum | cut -c 1-8 # 方法一
openssl rand -base64 4 # 方法二 openssl rand -base64 4 # 方法二
cat /proc/sys/kernel/random/uuid | cut -c 1-8 # 方法三 cat /proc/sys/kernel/random/uuid | cut -c 1-8 # 方法三
< /dev/urandom tr -dc A-Za-z0-9 | head -c8;echo # 方法四
date +%s | sha256sum | base64 | head -c 8;echo # 方法五
# 获取8位随机数字 # 获取8位随机数字
echo $RANDOM | cksum | cut -c 1-8 # 方法一 echo $RANDOM | cksum | cut -c 1-8 # 方法一

@ -179,6 +179,14 @@ comment
``` ```
```bash
# 查找当前目录xls文件名包含-字符文件并替换-为_
find . -type f -name '*-*.xls' | while read FILE ; do
newfile="$(echo ${FILE} |sed -e 's/-/_/')" ;
mv "${FILE}" "${newfile}" ;
done
```
### 根据-type文件类型进行搜索 ### 根据-type文件类型进行搜索
```bash ```bash

@ -1,17 +1,14 @@
# **tac** # **tac**
## 说明 ## 说明
**tac命令** 用于将文件已行为单位的反序输出,即第一行最后显示,最后一行先显示 **tac命令** 用于将文件已行为单位的反序输出,即第一行最后显示,最后一行先显示
## 选项 ## 选项
```markdown ```markdown
-b, --before 在行前而非行尾添加分隔标志 -b, --before 在行前而非行尾添加分隔标志
-r, --regex 将分隔标志视作正则表达式来解析 -r, --regex 将分隔标志视作正则表达式来解析
-s, --separator=字符串 使用指定字符串代替换行作为分隔标志 -s, --separator=字符串 使用指定字符串代替换行作为分隔标志
``` ```

@ -1,27 +1,25 @@
# tee # **tee**
## 说明 ## 说明
**tee命令** 用于将数据重定向到文件另一方面还可以提供一份重定向数据的副本作为后续命令的stdin。简单的说就是把数据重定向到给定文件和屏幕上 **tee命令** 用于将数据重定向到文件另一方面还可以提供一份重定向数据的副本作为后续命令的stdin。简单的说就是把数据重定向到给定文件和屏幕上
! !
存在缓存机制每1024个字节将输出一次。若从管道接收输入数据应该是缓冲区满才将数据转存到指定的文件中。 存在缓存机制每1024个字节将输出一次。若从管道接收输入数据应该是缓冲区满才将数据转存到指定的文件中。
若文件内容不到1024个字节则接收完从标准输入设备读入的数据后将刷新一次缓冲区并转存数据到指定文件 若文件内容不到1024个字节则接收完从标准输入设备读入的数据后将刷新一次缓冲区并转存数据到指定文件
## 选项 ## 选项
```markdown ```markdown
-a, --append 内容追加到给定的文件而非覆盖 -a, --append 内容追加到给定的文件而非覆盖
-i, --ignore-interrupts 忽略中断信号 -i, --ignore-interrupts 忽略中断信号
``` ```
## 选项 ## 实例
```bash ```bash
ls | tee out.txt # 在终端打印stdout同时重定向到文件中 ls | tee out.txt # 在终端打印stdout同时重定向到文件中
``` ```

@ -1,77 +1,76 @@
# **tr** # **tr**
## 说明 ## 说明
**tr命令** 可以对来自标准输入的字符进行替换、压缩和删除。它可以将一组字符变成另一组字符,经常用来编写优美的单行命令 **tr命令** 可以对来自标准输入的字符进行替换、压缩和删除。它可以将一组字符变成另一组字符,经常用来编写优美的单行命令
## 选项 ## 选项
```markdown ```markdown
用法tr [选项]... SET1 [SET2] 用法tr [选项]... SET1 [SET2]
从标准输入中替换、缩减和/或删除字符,并将结果写到标准输出 从标准输入中替换、缩减和/或删除字符,并将结果写到标准输出
-c, -C, --complement 首先补足SET1,即取代所有不属于第一字符集的字符 -c, -C, --complement 首先补足SET1,即取代所有不属于第一字符集的字符
-d, --delete 删除匹配SET1 的内容,并不作替换 -d, --delete 删除匹配SET1 的内容,并不作替换
-s, --squeeze-repeats 如果匹配于SET1 的字符在输入序列中存在连续的重复,在替换时会被统一缩为一个字符的长度 -s, --squeeze-repeats 如果匹配于SET1 的字符在输入序列中存在连续的重复,在替换时会被统一缩为一个字符的长度
-t, --truncate-set1 先将SET1 的长度截为和SET2 相等 -t, --truncate-set1 先将SET1 的长度截为和SET2 相等
SET 是一组字符串,一般都可按照字面含义理解。解析序列如下: SET 是一组字符串,一般都可按照字面含义理解。解析序列如下:
\NNN 八进制值为NNN 的字符(1 至3 个数位) \NNN 八进制值为NNN 的字符(1 至3 个数位)
\\ 反斜杠 \\ 反斜杠
\a 终端鸣响 \a 终端鸣响
\b 退格 \b 退格
\f 换页 \f 换页
\n 换行 \n 换行
\r 回车 \r 回车
\t 水平制表符 \t 水平制表符
\v 垂直制表符 \v 垂直制表符
字符1-字符2 从字符1 到字符2 的升序递增过程中经历的所有字符 字符1-字符2 从字符1 到字符2 的升序递增过程中经历的所有字符
[字符*] 在SET2 中适用指定字符会被连续复制直到吻合设置1 的长度 [字符*] 在SET2 中适用指定字符会被连续复制直到吻合设置1 的长度
[字符*次数] 对字符执行指定次数的复制,若次数以 0 开头则被视为八进制数 [字符*次数] 对字符执行指定次数的复制,若次数以 0 开头则被视为八进制数
[:alnum:] 所有的字母和数字 [:alnum:] 所有的字母和数字
[:alpha:] 所有的字母 [:alpha:] 所有的字母
[:blank:] 所有呈水平排列的空白字符 [:blank:] 所有呈水平排列的空白字符
[:cntrl:] 所有的控制字符 [:cntrl:] 所有的控制字符
[:digit:] 所有的数字 [:digit:] 所有的数字
[:graph:] 所有的可打印字符,不包括空格 [:graph:] 所有的可打印字符,不包括空格
[:lower:] 所有的小写字母 [:lower:] 所有的小写字母
[:print:] 所有的可打印字符,包括空格 [:print:] 所有的可打印字符,包括空格
[:punct:] 所有的标点字符 [:punct:] 所有的标点字符
[:space:] 所有呈水平或垂直排列的空白字符 [:space:] 所有呈水平或垂直排列的空白字符
[:upper:] 所有的大写字母 [:upper:] 所有的大写字母
[:xdigit:] 所有的十六进制数 [:xdigit:] 所有的十六进制数
[=字符=] 所有和指定字符相等的字符 [=字符=] 所有和指定字符相等的字符
使用方式: tr '[:lower:]' '[:upper:]' 使用方式: tr '[:lower:]' '[:upper:]'
仅在SET1 和SET2 都给出,同时没有-d 选项的时候才会进行替换 仅在SET1 和SET2 都给出,同时没有-d 选项的时候才会进行替换
仅在替换时才可能用到-t 选项。如果需要SET2 将被通过在末尾添加原来的末字符的方式 仅在替换时才可能用到-t 选项。如果需要SET2 将被通过在末尾添加原来的末字符的方式
补充到同SET1 等长。SET2 中多余的字符将被省略。只有[:lower:] 和[:upper:] 补充到同SET1 等长。SET2 中多余的字符将被省略。只有[:lower:] 和[:upper:]
以升序展开字符在用于替换时的SET2 中以成对表示大小写转换。-s 作用于SET1既不 以升序展开字符在用于替换时的SET2 中以成对表示大小写转换。-s 作用于SET1既不
替换也不删除否则在替换或展开后使用SET2 缩减 替换也不删除否则在替换或展开后使用SET2 缩减
``` ```
## 实例 ## 实例
```bash ```bash
echo "HELLO WORLD" | tr 'A-Z' 'a-z' # 将输入字符由大写转换为小写 echo "HELLO WORLD" | tr 'A-Z' 'a-z' # 将输入字符由大写转换为小写
echo 'Test' | tr '[:lower:]' '[:upper:]' # 将Test转换为大写 echo 'Test' | tr '[:lower:]' '[:upper:]' # 将Test转换为大写
echo "hello 123 world 456" | tr -d '0-9' # 使用tr删除字符 echo "hello 123 world 456" | tr -d '0-9' # 使用tr删除字符
cat text | tr '\t' ' ' # 将制表符转换为空格 cat text | tr '\t' ' ' # 将制表符转换为空格
tr -dc '[:print:]' < /dev/urandom # 过滤掉不能打印的内容 tr -dc '[:print:]' < /dev/urandom # 过滤掉不能打印的内容
# 字符集补集从输入文本中将不在补集中的所有字符删除此例中补集中包含了数字0~9、空格和换行符\n所以没有被删除其他字 # 字符集补集从输入文本中将不在补集中的所有字符删除此例中补集中包含了数字0~9、空格和换行符\n所以没有被删除其他字
# 符全部被删除了 # 符全部被删除了
echo aa.,a 1 b#$bb 2 c*/cc 3 ddd 4 | tr -d -c '0-9 \n' echo aa.,a 1 b#$bb 2 c*/cc 3 ddd 4 | tr -d -c '0-9 \n'
echo "thissss is a text linnnnnnne." | tr -s ' sn' # 用tr压缩字符可以压缩输入中重复的字符 echo "thissss is a text linnnnnnne." | tr -s ' sn' # 用tr压缩字符可以压缩输入中重复的字符
echo 1 2 3 4 5 6 7 8 9 | xargs -n1 | echo $[ $(tr '\n' '+') 0 ] # 巧妙使用tr做数字相加操作 echo 1 2 3 4 5 6 7 8 9 | xargs -n1 | echo $[ $(tr '\n' '+') 0 ] # 巧妙使用tr做数字相加操作
# 删除Windows文件“造成”的'^M'字符 # 删除Windows文件“造成”的'^M'字符
cat file | tr -s "\r" "\n" > new_file cat file | tr -s "\r" "\n" > new_file
cat file | tr -d "\r" > new_file cat file | tr -d "\r" > new_file
``` ```

@ -1,64 +1,56 @@
## **whatis** # **whatis**
## 说明 ## 说明
**whatis命令** 是用于查询一个命令执行什么功能,并将查询结果打印到终端上 **whatis命令** 是用于查询一个命令执行什么功能,并将查询结果打印到终端上
whatis命令在用`catman -w`命令创建的数据库中查找command参数指定的命令、系统调用、库函数或特殊文件名。whatis命令显示手册部 whatis命令在用`catman -w`命令创建的数据库中查找command参数指定的命令、系统调用、库函数或特殊文件名。whatis命令显示手册部
分的页眉行。然后可以发出man命令以获取附加的信息。whatis命令等同于使用`man -f`命令 分的页眉行。然后可以发出man命令以获取附加的信息。whatis命令等同于使用`man -f`命令
## 选项 ## 选项
```markdown ```markdown
Usage: whatis [OPTION...] 关键词... Usage: whatis [OPTION...] 关键词...
-d, --debug 输出调试信息 -d, --debug 输出调试信息
-v, --verbose 输出详细的警告信息 -v, --verbose 输出详细的警告信息
-r, --regex 把每个关键词都当作正则表达式解读 -r, --regex 把每个关键词都当作正则表达式解读
-w, --wildcard 关键词里包含通配符 -w, --wildcard 关键词里包含通配符
-l, --long 不要把输出按终端宽度截断 -l, --long 不要把输出按终端宽度截断
-C, --config-file=文件 使用该用户设置文件 -C, --config-file=文件 使用该用户设置文件
-L, --locale=区域 定义本次搜索所使用的区域设置 -L, --locale=区域 定义本次搜索所使用的区域设置
-m, --systems=系统 use manual pages from other systems -m, --systems=系统 use manual pages from other systems
-M, --manpath=路径 设置搜索手册页的路径为“路径” -M, --manpath=路径 设置搜索手册页的路径为“路径”
-s, --sections=列表, --section=列表 -s, --sections=列表, --section=列表 search only these sections (colon-separated)
search only these sections (colon-separated)
-?, --help give this help list Mandatory or optional arguments to long options are also mandatory or optional
--usage give a short usage message for any corresponding short options.
-V, --version print program version ```
Mandatory or optional arguments to long options are also mandatory or optional ## 实例
for any corresponding short options.
``` ```bash
whatis man
: << comment
输出详解:
## 实例 man (1) - format and display the on-line manual pages
man (1p) - display system documentation
```bash man (7) - macros to format man pages
whatis man man (rpm) - A set of documentation tools: man, apropos and whatis.
: << comment man-pages (rpm) - Man (manual) pages from the Linux Documentation Project.
输出详解: man.config [man] (5) - configuration data for man
man (1) - format and display the on-line manual pages
man (1p) - display system documentation man页面所属的分类标识(常用的是分类1和分类3)
man (7) - macros to format man pages
man (rpm) - A set of documentation tools: man, apropos and whatis. (1)、用户可以操作的命令或者是可执行文件
man-pages (rpm) - Man (manual) pages from the Linux Documentation Project. (2)、系统核心可调用的函数与工具等
man.config [man] (5) - configuration data for man (3)、一些常用的函数与数据库
(4)、设备文件的说明
man页面所属的分类标识(常用的是分类1和分类3) (5)、设置文件或者某些文件的格式
(6)、游戏
(1)、用户可以操作的命令或者是可执行文件 (7)、惯例与协议等。例如Linux标准文件系统、网络协议、ASCⅡ码等说明内容
(2)、系统核心可调用的函数与工具等 (8)、系统管理员可用的管理条令
(3)、一些常用的函数与数据库 (9)、与内核有关的文件
(4)、设备文件的说明 comment
(5)、设置文件或者某些文件的格式
(6)、游戏 ```
(7)、惯例与协议等。例如Linux标准文件系统、网络协议、ASCⅡ码等说明内容
(8)、系统管理员可用的管理条令
(9)、与内核有关的文件
comment
```

@ -1,9 +1,20 @@
def digital_to_chinese(digital): def digital_to_chinese(digital):
str_digital = str(digital) str_digital = str(digital)
chinese = {'1': '', '2': '', '3': '', '4': '', '5': '', '6': '', '7': '', '8': '', '9': '', '0': ''} chinese = {
chinese2 = ['', '', '', '', '', '', ''] "1": "",
jiao = '' "2": "",
bs = str_digital.split('.') "3": "",
"4": "",
"5": "",
"6": "",
"7": "",
"8": "",
"9": "",
"0": "",
}
chinese2 = ["", "", "", "", "", "", ""]
jiao = ""
bs = str_digital.split(".")
yuan = bs[0] yuan = bs[0]
if len(bs) > 1: if len(bs) > 1:
jiao = bs[1] jiao = bs[1]
@ -11,13 +22,13 @@ def digital_to_chinese(digital):
count = 0 count = 0
for i in range(len(yuan)): for i in range(len(yuan)):
if i == 0: if i == 0:
r_yuan[i] += '' r_yuan[i] += ""
continue continue
r_yuan[i] += chinese2[count] r_yuan[i] += chinese2[count]
count += 1 count += 1
if count == 4: if count == 4:
count = 0 count = 0
chinese2[3] = '亿' chinese2[3] = "亿"
s_jiao = [i for i in jiao][:3] # 去掉小于厘之后的 s_jiao = [i for i in jiao][:3] # 去掉小于厘之后的
@ -27,7 +38,7 @@ def digital_to_chinese(digital):
j_count -= 1 j_count -= 1
last = [i for i in reversed(r_yuan)] + s_jiao last = [i for i in reversed(r_yuan)] + s_jiao
last_str = ''.join(last) last_str = "".join(last)
print(str_digital) print(str_digital)
print(last_str) print(last_str)
for i in range(len(last_str)): for i in range(len(last_str)):
@ -39,7 +50,7 @@ def digital_to_chinese(digital):
# number = float(input("输入需要转换的数字:")) # number = float(input("输入需要转换的数字:"))
number = float(4650) number = float(3000)
if __name__ == '__main__': if __name__ == "__main__":
digital_to_chinese(number) digital_to_chinese(number)

@ -4,7 +4,7 @@ import json
# 如有报错Result window is too large, from + size must be less than or equal to: [10000] # 如有报错Result window is too large, from + size must be less than or equal to: [10000]
# 执行以下修改【不再使用此方式防止内存溢出使用如下的scroll api处理】 # 执行以下修改【不再使用此方式防止内存溢出使用如下的scroll api处理】
# curl -XPUT "http://192.168.2.15:9200/props_change_log/_settings" -d '{ "index" : { "max_result_window" : 1000000 } }' # curl -XPUT "http://192.168.2.15:9200/index/_settings" -d '{ "index" : { "max_result_window" : 1000000 } }'
# 定义数据写入的文件路径 # 定义数据写入的文件路径
root_path = "D:/xxx.json" root_path = "D:/xxx.json"
@ -18,8 +18,8 @@ def record_docs(root_path, record):
# 定义配置 # 定义配置
host = "192.168.2.15:9200" host = "192.168.2.15:9200"
# index = "props_change_log" # index = "index"
index = "time_limited_props_log" index = "index"
scroll = "1m" scroll = "1m"
size = 1000 size = 1000
body = { body = {
@ -29,7 +29,7 @@ body = {
es = Elasticsearch(hosts=host) es = Elasticsearch(hosts=host)
# es.indices.refresh(index="by_petskill_log") # es.indices.refresh(index="index")
# 利用json.dumps处理hits数据,将返回str类型 # 利用json.dumps处理hits数据,将返回str类型

@ -3,7 +3,7 @@ from selenium.webdriver.chrome.webdriver import Service
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions, expected_conditions, wait from selenium.webdriver.support import expected_conditions, wait
from selenium.common.exceptions import ( from selenium.common.exceptions import (
ElementNotSelectableException, ElementNotSelectableException,
ElementNotVisibleException, ElementNotVisibleException,
@ -64,22 +64,23 @@ browser.current_window_handle
# 上下文管理器启动驱动程序 # 上下文管理器启动驱动程序
with webdriver.Firefox() as browser: with webdriver.Firefox() as browser:
browser.get("https://www.xxx.com") browser.get("https://www.xxx.com")
# 设置等待时间 # 设置显式等待时间通常和该类的WebDriverWait.until()方法和WebDriverWait.until_not()方法结合使用
wait_time = WebDriverWait(browser, 10) # 每隔2秒检查一次若条件成立则进行下一步否则继续等待直到超过设置的10秒然后抛出TimeoutException
wait_time = WebDriverWait(browser, 10, 2)
# 存储原始窗口id # 存储原始窗口id
origin_window = browser.current_window_handle origin_window = browser.current_window_handle
# 检查其他未打开的窗口 # 检查其他未打开的窗口
assert len(browser.window_handles) == 1 assert len(browser.window_handles) == 1
browser.find_element_by_link_text("new window").click() browser.find_element_by_link_text("new window").click()
# 等待新窗口或标签页 # 等待新窗口或标签页
wait.until(EC.number_of_windows_to_be(2)) wait.until(expected_conditions.number_of_windows_to_be(2))
# 循环找到新的窗口句柄 # 循环找到新的窗口句柄
for window_handle in browser.window_handles: for window_handle in browser.window_handles:
if window_handle != origin_window: if window_handle != origin_window:
browser.switch_to.window(window_handle) browser.switch_to.window(window_handle)
break break
# 等待加载完成 发 # 等待加载完成 发
wait.until(EC.title_is("xxx")) wait.until(expected_conditions.title_is("xxx"))
# 创建新的标签页和窗口,此特性只适用于selenium4 # 创建新的标签页和窗口,此特性只适用于selenium4
browser.switch_to.new_window("tab") browser.switch_to.new_window("tab")
@ -114,7 +115,8 @@ browser.maximize_window() # 最大化窗口
# 隐式等待是告诉WebDriver如果在查找一个或多个不是立即可用的元素时轮询DOM一段时间。默认设置为0表示禁用 # 隐式等待是告诉WebDriver如果在查找一个或多个不是立即可用的元素时轮询DOM一段时间。默认设置为0表示禁用
# 一旦设置好,隐式等待就被设置为会话的生命周期 # 一旦设置好,隐式等待就被设置为会话的生命周期
browser.implicitly_wait(10) # 等待10秒 # 在页面完全加载完毕期间等待10秒若10秒还未加载完则进行下一步
browser.implicitly_wait(10)
# 流畅等待定义等待条件的最大时间量及检查条件的频率 # 流畅等待定义等待条件的最大时间量及检查条件的频率
# 例如设置等待来忽略NoSuchElementException异常 # 例如设置等待来忽略NoSuchElementException异常
@ -125,11 +127,11 @@ wait = WebDriverWait(
poll_frequency=1, poll_frequency=1,
ignored_exceptions=[ElementNotVisibleException, ElementNotSelectableException], ignored_exceptions=[ElementNotVisibleException, ElementNotSelectableException],
) )
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div"))) element = wait.until(expected_conditions.element_to_be_clickable((By.XPATH, "//div")))
# js的alerts警告框 # js的alerts警告框
browser.find_element_by_link_text("xxx").click() # browser.find_element_by_link_text("xxx").click()
# 等待alert窗口显示后存储到变量中 # 等待alert窗口显示后存储到变量中
alert = wait.until(expected_conditions.alert_is_present()) alert = wait.until(expected_conditions.alert_is_present())
# 将警告中的文本存储到变量 # 将警告中的文本存储到变量

@ -4,33 +4,30 @@ import subprocess
from shutil import copy2 from shutil import copy2
xxxpath="xxx/xxx" xxxpath="xxx/xxx"
# 私钥可以被paramiko使用执行转换命令ssh-keygen -p -m PEM -f ~/.ssh/copyid_rsa # RSA格式私钥可以被paramiko使用执行转换命令ssh-keygen -p -m PEM -t RSA -f ~/.ssh/copyid_rsa
key_path = 'xxx/.ssh/copyid_rsa' key_path = 'xxx/.ssh/copyid_rsa'
# 定义上传函数,paramiko通过公钥免密连接 # 定义上传函数,paramiko通过公钥免密连接
def upload(root_path, key_private_path): def upload(root_path, privateKey):
ssh = paramiko.SSHClient() client = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='服务器ip', port='端口', client.connect(hostname='服务器ip', port='端口',
username='用户', key_filename=key_private_path, allow_agent=True) username='用户', key_filename=privateKey, allow_agent=True)
sftp = ssh.open_sftp() sftp = client.open_sftp()
for root, dirs, files in os.walk(xxxpath): # 利用os的walk函数获取本地目录文件列表
root_linux = root.replace('\\', '/') for dirspath, dirsname, files in os.walk(xxxpath):
root_linux = dirspath.replace('\\', '/')
# sftp的mkdir函数不支持创建多级目录固使用ssh连接后linux原生命令创建 # sftp的mkdir函数不支持创建多级目录固使用ssh连接后linux原生命令创建
remote_path = os.path.join('xxx/path', root_linux[29:]) remote_path = os.path.join('xxx/path', root_linux[29:])
stdin, stdout, stderr = ssh.exec_command( stdin, stdout, stderr = client.exec_command(
''.join(['mkdir -p ' + remote_path])) ''.join(['mkdir -p ' + remote_path]))
# 利用os的walk函数获取本地目录文件列表
for root, dirs, files in os.walk(xxxpath):
root_linux = root.replace('\\', '/')
remote_path = os.path.join('xxx/path/', root_linux[29:])
for file in files: for file in files:
upload_file = os.path.join(root_linux, file).replace('\\', '/') upload_file = os.path.join(root_linux, file).replace('\\', '/')
print(u'Put files...' + upload_file) print(u'Put files...' + upload_file)
sftp.put(upload_file, os.path.join( sftp.put(upload_file, os.path.join(
remote_path, file).replace('\\', '/')) remote_path, file).replace('\\', '/'))
ssh.close() client.close()
sftp.close() sftp.close()

Loading…
Cancel
Save