# bin_check.py
dict_test = {1: 'fail', 2: 'fail', 3: 'fail', 4: 'fail', 5: 'fail', 6: 'fail', 7: 'pass', 8: 'pass', 9: 'pass',
10: 'pass'}
def bin_check(dict_test: dict, mid):
if int(dict_test[mid]) > 10:
return "pass"
else:
return "fail"
print(dict_test.get[mid])
# 从 a.txt 读取参数,转成字典的格式
# with open('a.txt', 'r') as file:
# param_list = [line.strip() for line in file]
#
# my_dict = {idx: value for idx, value in enumerate(param_list)}
case_name = 'a.txt'
def change_type(case_name):
with open(case_name, 'r') as file:
param_list = [line.strip() for line in file]
my_dict = {idx: value for idx, value in enumerate(param_list)}
return my_dict
def bi_check(low, high, dict_test):
'''
:param low:
:param high:
:param dict_test:
:return:
'''
print('low-------------------------------', low)
print('high------------------------------', high)
if low + 1 >= high:
return
mid = (low + high) // 2
print('mid is ', mid)
print('value is',dict_test[mid])
# 执行命令后,返回pass 或 fail的结果
# 单次执行命令需要提供的参数是 所有需要去二分的数据
mid_result = bin_check(dict_test, mid)
# 根据执行结果,去重新定界二分的范围。
if mid_result == 'pass':
high = mid
print(mid, ':pass')
if mid_result == 'fail':
low = mid
print(mid, ':fail')
print('----------------------------------------------------------------------end')
bi_check(low, high, dict_test)
# 参数放在txt文件里,转换成字典类型。
dict_test = change_type(case_name)
print(dict_test)
low = 0
high = len(dict_test) - 1
bi_check(low, high, dict_test)
# bin_check.py
import subprocess
import os
import sys
# 以当前的文件的目录为坐标
cur_path = os.path.abspath(os.path.dirname(__file__))
run_num = 0
# 把需要二分的包转换成自己需要的格式,result 结果是'' pass, fail ,lost package(下载的包不符合我们自己的要求,就标记这个) 。
# 最好生成列表套字典的格式,方便排序,记录
# [{'cann_pack_name': '20240620_093006936_I4018384', 'result': ''},]
# 考虑转化时,过滤掉空行
def change_type(case_txt):
with open(case_txt, 'r') as file:
param_list = [line.strip() for line in file if line.count("_") == 2]
my_dict = [{'cann_pack_name': i, 'result': ''} for i in param_list]
return my_dict
# 下载CANN包
# 创建一个cann_package_name的包名,在这个目录里,下载包,检查包,安装包。
# 保证最后下载好的包放在cann_package_name 这个包名的目录里就行。
def down_cann_pak_pre(cann_pack_name):
os.chdir(cur_path)
os.system('rm -rf {}'.format(cann_pack_name))
os.system('mkdir {}'.format(cann_pack_name))
os.system('cp download_only.py {}'.format(cann_pack_name))
os.chdir(os.path.join(cur_path, cann_pack_name))
os.system('pwd')
os.system('python3 download_only.py {}'.format(cann_pack_name))
# 检测是否有自己需要的CANN包
# 看是否需要简单优化一下,尽量不传入全名。
def check_CANN_package(cann_pack_name, cann_lsit):
# cann_pack_name = '20240618_164626868_I460ad83'
# 判断是这次的包是否符合要求
is_re_down = 'no'
for cann_name in cann_lsit:
file_path = "/".join([cur_path, cann_pack_name, cann_name]) # 文件路径
print(file_path)
if os.path.isfile(file_path):
file_size = os.path.getsize(file_path)
file_size = file_size // (1024 * 1024)
# 包文件小于1MB的话,可能是下载有问题,当成空文件处理。
if file_size >= 1:
print('文件-----[{:<60}] [{:<10}]MB status=[OK]'.format(cann_name, file_size))
else:
print('文件-----[{:<60}] [{:<10}]MB status=[Fail]'.format(cann_name, file_size))
is_re_down = 'yes'
# 如果文件有问题,这次装包作废,需要重新选包并且重新生成新的 case_txt
else:
is_re_down = 'yes'
# 检查完成所有的包之后,再返回。
print('is_re_down is ', is_re_down)
return is_re_down
# 下载包后,保证安装包脚本,和包在一个路径下。
def install_package(cann_pack_name):
os.chdir(cur_path)
os.system('cp install_only.sh {}'.format(cann_pack_name))
os.system('pwd')
# os.system('cd {}/{}'.format(cur_path, cann_pack_name))
os.chdir(os.path.join(cur_path, cann_pack_name))
os.system('pwd')
os.system("./install_only.sh")
# 执行命令并且获取返回值,
# case_name support_custom_cache_path_001
# cann_pack_name 20240331_000121881_newest
def excute_order(case_name, cann_pack_name):
os.chdir(cur_path)
result = subprocess.run(['./zrexfu.sh', case_name, cann_pack_name])
if result.returncode == 0:
print('pass')
return "pass"
elif result.returncode == 1:
print('fail')
return "fail"
# 从 a.txt 读取参数,转成字典的格式
# with open('a.txt', 'r') as file:
# param_list = [line.strip() for line in file]
#
# my_dict = {idx: value for idx, value in enumerate(param_list)}
# 重新生成my_dict:
def re_change_type(case_name_de):
with open(case_txt, 'r') as file:
param_list = [line.strip() for line in file]
my_dict = {idx: value for idx, value in enumerate(param_list)}
def test_excute_order(j, dict_test):
# run_num = len(dict_test) - 1
# for j in range(run_num):
cann_package = dict_test[j]['cann_pack_name']
if '20240620_' in cann_package:
case_result = 'pass'
elif '20240621_' in cann_package:
case_result = 'fail'
else:
print('key值是', dict_test[j]['cann_pack_name'])
return case_result
# 二分的命令
def bi_check(low, high, case_name, dict_test, dict_test_ori):
'''
low:二分的开始
high:二分结束
case_name:二分的用例名字
dict_test:二分的数据都在里面
dect_test_ori:二分数据的记录,更新结果。
'''
for j in dict_test_ori:
print(j)
global run_num
run_num = run_num + 1
# high是二分数据的最大值
# high = len(dict_test) - 1
print('low-------------------------------', low, dict_test[low])
print('high------------------------------', high, dict_test[high])
# 可以考虑每次到这里就更新数据,或者打印一下需要展示的数据。
if low + 1 >= high:
print('----------------------------结果如下---------------------------------')
for i in dict_test_ori:
print(i)
sys.exit()
mid = (low + high) // 2
print('mid is ', mid)
cann_pack_name = dict_test[mid]["cann_pack_name"] # 取出中间mid的值,即20240621_172455102_Ic545fa3
print('*****************************************************************************************')
print(f'This is the [ {run_num} ] check , and cann_pack_name is [{cann_pack_name}]')
print('*****************************************************************************************')
# 下载包
down_cann_pak_pre(cann_pack_name)
# 检查需要安装的包是否齐全,不齐全result_is_rerun 值返回yes.
result_is_rerun = check_CANN_package(cann_pack_name, cann_lsit=cann_lsit_date)
# 如果包有问题,不满足自己的安装需要,需要更新dict_test
if result_is_rerun == 'yes':
for i in range(len(dict_test_ori)):
if dict_test_ori[i]['cann_pack_name'] == cann_pack_name:
dict_test_ori[i]['result'] = 'lost_package' + str(run_num)
print(dict_test_ori[i]['result'], "********lost_package***********")
# 直接删除dict_test[mid]这个值,更新dict_test
a = dict_test.pop(mid)
print('This cann_pack is not satisfy needs', a)
# 对于更新后的dict_test。需要有新的high. low不变。high 是最大值,少一个包,high就少了一个1.
high = high - 1
bi_check(low, high, case_name, dict_test, dict_test_ori)
# 安装CANN包。考虑安装后是否自动删除CANN包。
install_package(cann_pack_name)
# 跑用例
mid_result = excute_order(case_name, cann_pack_name)
# mid_result = excute_case(mid, dict_test)
# 根据执行结果,去重新定界二分的范围。
if mid_result == 'pass':
high = mid
print(f'{high}:{cann_pack_name} :pass')
for i in range(len(dict_test_ori)):
if dict_test_ori[i]['cann_pack_name'] == cann_pack_name:
dict_test_ori[i]['result'] = 'pass' + str(run_num)
elif mid_result == 'fail':
low = mid
print(f'{low}:{cann_pack_name} :fail')
for i in range(len(dict_test_ori)):
if dict_test_ori[i]['cann_pack_name'] == cann_pack_name:
dict_test_ori[i]['result'] = 'fail' + str(run_num)
else:
print(f'{dict_test_ori[mid]} Did not get reuslt ')
return
print('----------------------------------------------------------------------end')
bi_check(low,high, case_name, dict_test, dict_test_ori)
if __name__ == '__main__':
# 参数放在txt文件里 。
case_txt = 'a.txt'
file_path = "/".join([cur_path, case_txt]) # 文件路径
if not os.path.isfile(file_path):
print('--------------------------缺少{},需要把数据放到{}这个文件里---------------------------'.format(case_txt,
case_txt))
exit()
# dict_test=[{'cann_pack_name': '20240621_205524724_I776ef4d', 'result': ''}, {'cann_pack_name': '20240621_205458628_Ia3dbf1c', 'result': ''},]
dict_test = change_type(case_txt) # 考虑python直接复制问题,还有一个是怎么给cann_pack_name打上标签的问题。
# 用来做一个最终记录
dict_test_ori = change_type(case_txt)
print(dict_test)
for i in dict_test:
print(i)
# low是第一个数
low = 0
high = len(dict_test) - 1
run_num = 0
# 用例名和 二分必须要安装的包的名字。
cann1 = 'CANN-aoe-7.3.t10.0.b528-linux.x86_64.run'
cann2 = 'CANN-compiler-7.3.t10.0.b528-linux.x86_64.run'
cann3 = 'CANN-fwkplugin-7.3.t10.0.b528-linux.x86_64.run'
cann4 = 'CANN-hccl-7.3.t10.0.b528-linux.x86_64.run'
cann5 = 'CANN-opp-7.3.t10.0.b528-linux.x86_64.run'
cann6 = 'CANN-runtime-7.3.t10.0.b528-linux.x86_64.run'
cann7 = 'CANN-toolkit-7.3.t10.0.b528-linux.x86_64.run'
case_name = 'case21_op_while_staticShape_atmFalse_infer'
cann_lsit_date = [cann1, cann2, cann3, cann4, cann5, cann6, cann7]
# cann_pack_name = '20240331_000121881_newest'
print('本次二分的用例是', case_name)
# 防止误跑
user_input = input("确认运行输入YES:")
if user_input == 'YES':
bi_check(low, high, case_name, dict_test, dict_test_ori)
else:
print("----------------退出程序---------------------")
import subprocess
import os
import sys
# 以当前的文件的目录为坐标
cur_path = os.path.abspath(os.path.dirname(__file__))
run_num = 0
# 把需要二分的包转换成自己需要的格式,result 结果是'' pass, fail ,lost package(下载的包不符合我们自己的要求,就标记这个) 。
# 最好生成列表套字典的格式,方便排序,记录
# [{'cann_pack_name': '20240620_093006936_I4018384', 'result': ''},]
# 考虑转化时,过滤掉空行
def change_type(case_txt):
with open(case_txt, 'r') as file:
param_list = [line.strip() for line in file if line.count("_") == 2]
my_dict = [{'cann_pack_name': i, 'result': ''} for i in param_list]
return my_dict
# 下载CANN包
# 创建一个cann_package_name的包名 20240620_093006936_I4018384 ,在这个目录里,下载包,检查包,安装包。
# 保证最后下载好的包放在cann_package_name 这个包名的目录里就行。
def down_cann_pak_pre(cann_pack_name):
os.chdir(cur_path)
os.system('rm -rf {}'.format(cann_pack_name))
os.system('mkdir {}'.format(cann_pack_name))
os.system('cp download_only.py {}'.format(cann_pack_name))
os.chdir(os.path.join(cur_path, cann_pack_name))
os.system('pwd')
os.system('python3 download_only.py {}'.format(cann_pack_name))
# 检测是否有自己需要的CANN包
# 看是否需要简单优化一下,尽量不传入全名。
def check_CANN_package(cann_pack_name, cann_lsit):
# cann_pack_name = '20240618_164626868_I460ad83'
# 判断是这次的包是否符合要求
is_re_down = 'no'
for cann_name in cann_lsit:
file_path = "/".join([cur_path, cann_pack_name, cann_name]) # 文件路径
print(file_path)
if os.path.isfile(file_path):
file_size = os.path.getsize(file_path)
file_size = file_size // (1024 * 1024)
# 包文件小于1MB的话,可能是下载有问题,当成空文件处理。可以手动确认一下
if file_size >= 1:
print('文件-----[{:<60}] [{:<10}]MB status=[OK]'.format(cann_name, file_size))
else:
print('文件-----[{:<60}] [{:<10}]MB status=[Fail]'.format(cann_name, file_size))
is_re_down = 'yes'
# 如果文件有问题,这次装包作废,需要重新选包并且重新生成新的 case_txt
else:
is_re_down = 'yes'
# 检查完成所有的包之后。
print('is_re_down is ', is_re_down)
return is_re_down
# 下载包后,保证安装包脚本,和包在一个路径下。
def install_package(cann_pack_name):
os.chdir(cur_path)
os.system('cp install_only.sh {}'.format(cann_pack_name))
os.system('pwd')
# os.system('cd {}/{}'.format(cur_path, cann_pack_name))
os.chdir(os.path.join(cur_path, cann_pack_name))
os.system('pwd')
os.system("./install_only.sh")
# 执行命令并且获取返回值,
# case_name support_custom_cache_path_001
# cann_pack_name 20240331_000121881_newest
def excute_order(case_name, cann_pack_name):
os.chdir(cur_path)
result = subprocess.run(['./zrexfu.sh', case_name, cann_pack_name])
if result.returncode == 0:
print('------pass------')
return "pass"
elif result.returncode == 1:
print('-------fail--------')
return "fail"
# 从 a.txt 读取参数,转成字典的格式
# with open('a.txt', 'r') as file:
# param_list = [line.strip() for line in file]
#
# my_dict = {idx: value for idx, value in enumerate(param_list)}
# 调试函数
def test_excute_order(j, dict_test):
# run_num = len(dict_test) - 1
# for j in range(run_num):
cann_package = dict_test[j]['cann_pack_name']
if '20240620_' in cann_package:
case_result = 'pass'
elif '20240621_' in cann_package:
case_result = 'fail'
else:
print('key值是', dict_test[j]['cann_pack_name'])
return case_result
# 二分的命令
def bi_check(low, high, case_name, dict_test, dict_test_ori):
'''
low:二分的开始
high:二分结束
case_name:二分的用例名字
dict_test:实时二分的数据都在里面
dect_test_ori:记录二分数据的记录,更新结果。
'''
# 每次二分前,打印当前的二分结果
# for j in dict_test_ori:
# print(j)
for i in dict_test_ori:
print(i)
global run_num
run_num = run_num + 1
# high是二分数据的最大值
# high = len(dict_test) - 1
print('low-------------------------------', low, dict_test[low])
print('high------------------------------', high, dict_test[high])
# 可以考虑每次到这里就更新数据,或者打印一下需要展示的数据。
if low + 1 >= high:
print('----------------------------结果如下---------------------------------')
for i in dict_test_ori:
print(i)
sys.exit()
mid = (low + high) // 2
print('mid is ', mid)
cann_pack_name = dict_test[mid]["cann_pack_name"] # 取出中间mid的值,即20240621_172455102_Ic545fa3
print('*****************************************************************************************')
print(f'This is the [ {run_num} ] check , and cann_pack_name is [{cann_pack_name}]')
print('*****************************************************************************************')
# 下载包
down_cann_pak_pre(cann_pack_name)
# 检查需要安装的包是否齐全,不齐全result_is_rerun 值返回 yes.
result_is_rerun = check_CANN_package(cann_pack_name, cann_lsit=cann_lsit_date)
# 如果包有问题,不满足自己的安装需要,需要更新dict_test,删除这个时间戳,重排
if result_is_rerun == 'yes':
for i in range(len(dict_test_ori)):
if dict_test_ori[i]['cann_pack_name'] == cann_pack_name:
dict_test_ori[i]['result'] = 'lost_package' + str(run_num)
print(dict_test_ori[i]['result'], "********lost_package***********")
# 直接删除dict_test[mid]这个值,更新dict_test
a = dict_test.pop(mid)
print('This cann_pack is not satisfy needs', a)
# 对于更新后的dict_test。需要有新的high. low不变。high 是最大值,少一个包,high就少了一个1.
high = high - 1
bi_check(low, high, case_name, dict_test, dict_test_ori)
# 安装CANN包。考虑安装后是否自动删除CANN包。
install_package(cann_pack_name)
# 跑用例
mid_result = excute_order(case_name, cann_pack_name)
# mid_result = excute_case(mid, dict_test)
# 根据执行结果,去重新定界二分的范围。
if mid_result == 'pass':
high = mid
print(f'{high}:{cann_pack_name} :pass')
for i in range(len(dict_test_ori)):
if dict_test_ori[i]['cann_pack_name'] == cann_pack_name:
dict_test_ori[i]['result'] = 'pass' + str(run_num)
elif mid_result == 'fail':
low = mid
print(f'{low}:{cann_pack_name} :fail')
for i in range(len(dict_test_ori)):
if dict_test_ori[i]['cann_pack_name'] == cann_pack_name:
dict_test_ori[i]['result'] = 'fail' + str(run_num)
else:
print(f'{dict_test_ori[mid]} Did not get reuslt ')
return
print('----------------------------------------------------------------------end')
bi_check(low, high, case_name, dict_test, dict_test_ori)
if __name__ == '__main__':
# 参数放在txt文件里 。
if len(sys.argv) != 2:
exit('运行参数有误,按照python3 xxxx.py case_name 方式运行')
# 本次二分跑的用例名
case_name = sys.argv[1]
# a.txt文件放在二分脚本同级目录下
case_txt = 'a.txt'
file_path = "/".join([cur_path, case_txt]) # 文件路径
if not os.path.isfile(file_path):
print('--------------------------缺少{},需要把数据放到{}这个文件里---------------------------'.format(case_txt,
case_txt))
exit()
# dict_test=[{'cann_pack_name': '20240621_205524724_I776ef4d', 'result': ''}, {'cann_pack_name': '20240621_205458628_Ia3dbf1c', 'result': ''},]
dict_test = change_type(case_txt) # 考虑python直接复制问题,还有一个是怎么给cann_pack_name打上标签的问题。
# dict_test_ori用来做一个最终记录
dict_test_ori = change_type(case_txt)
print(dict_test)
# for i in dict_test:
# print(i)
for index, item in enumerate(dict_test_ori, start=0):
print(f"{index} :{item}")
# low是第一个数
low = 0
high = len(dict_test) - 1
# 记录第几次二分
run_num = 0
# 明确好二分必须要安装的CANN包的名字,如果这个时间戳的包缺少这个CANN包, 就重新选定。
cann1 = 'CANN-aoe-7.3.t10.0.b528-linux.x86_64.run'
cann2 = 'CANN-compiler-7.3.t10.0.b528-linux.x86_64.run'
cann3 = 'CANN-fwkplugin-7.3.t10.0.b528-linux.x86_64.run'
cann4 = 'CANN-hccl-7.3.t10.0.b528-linux.x86_64.run'
cann5 = 'CANN-opp-7.3.t10.0.b528-linux.x86_64.run'
cann6 = 'CANN-runtime-7.3.t10.0.b528-linux.x86_64.run'
cann7 = 'CANN-toolkit-7.3.t10.0.b528-linux.x86_64.run'
cann_lsit_date = [cann1, cann2, cann3, cann4, cann5, cann6, cann7]
# cann_pack_name = '20240331_000121881_newest'
case_name = sys.argv[1]
if len(cann_lsit_date) > 0:
print('本次二分必须安装的包如下:')
for i in cann_lsit_date:
print(i)
print('本次二分的用例是', case_name)
# 确认下,防止误跑
user_input = input("确认运行输入YES:")
if user_input == 'YES':
bi_check(low, high, case_name, dict_test, dict_test_ori)
else:
print("----------------退出程序---------------------" )
2、telnetlib 库怎么使用,我想用我的服务器。连接另一个服务器,然后远程进入到/home/zmx文件夹下,打印当前的目录下的文件名,然后传输回来
telnetlib
库是 Python 标准库的一部分,用于通过 Telnet 协议与远程服务器进行交互。然而,由于 Telnet 协议本身不加密数据,因此它不适合传输敏感信息(如密码)或执行需要高安全性的任务。在现代环境中,通常建议使用 SSH(通过 paramiko
或 fabric
等库)来替代 Telnet。
不过,如果你确实需要使用 telnetlib
并且了解相关的安全风险,以下是一个基本的示例,展示了如何使用 telnetlib
连接到远程服务器,进入指定目录,并尝试打印当前目录下的文件名。请注意,这个示例假设远程服务器使用的是类似于 Unix 的系统,并且你有足够的权限来执行这些操作。
import telnetlib
# 远程服务器的地址和端口号
host = 'your_remote_server_ip'
port = 23 # Telnet 默认端口
# 用户名和密码
username = 'your_username'
password = 'your_password' # 请注意,在脚本中硬编码密码是不安全的做法
# 要进入的目录
target_directory = '/home/zmx'
# 创建 Telnet 连接对象
tn = telnetlib.Telnet(host, port, timeout=10) # 设置超时时间为 10 秒
try:
# 读取登录提示并发送用户名
tn.read_until(b'login: ')
tn.write(username.encode('ascii') + b'\r\n')
# 读取密码提示并发送密码
tn.read_until(b'Password: ')
tn.write(password.encode('ascii') + b'\r\n')
# 检查是否登录成功(这取决于远程服务器的登录后提示)
# 这里我们假设登录成功后会出现一个提示符,比如 '$' 或 '#'
prompt = tn.read_until(b'$ ' if username == 'your_non_root_username' else b'# ')
# 发送命令进入目标目录
tn.write((f'cd {target_directory}\r\n').encode('ascii'))
# 再次读取提示符以确认目录更改
# 注意:这里我们假设没有错误发生,并且目录更改成功
# 在实际使用中,你应该检查命令的输出以确认其成功执行
tn.read_until(b'$ ' if username == 'your_non_root_username' else b'# ')
# 发送命令列出当前目录的文件
tn.write(b'ls\r\n')
# 读取并打印文件列表
# 注意:这里我们假设输出不会太长,并且没有分页器干扰
file_list = tn.read_until(b'$ ' if username == 'your_non_root_username' else b'# ').decode('ascii')
print(file_list)
finally:
# 关闭连接
tn.close()
重要注意事项:
-
安全性:如前所述,Telnet 不加密数据,因此用户名、密码和所有其他通信都可能被截获。在生产环境中,应使用 SSH 或其他安全协议。
-
错误处理:上面的代码没有包含任何错误处理逻辑。在实际应用中,你应该添加适当的异常处理来捕获和处理可能发生的错误(如连接失败、认证失败、命令执行失败等)。
-
编码:上面的代码假设远程服务器的提示符和文件系统使用 ASCII 编码。如果远程服务器使用不同的字符编码(如 UTF-8),你可能需要相应地调整编码设置。
-
分页器:如果远程服务器的
ls
命令配置了分页器(如less
或more
),则上面的代码可能无法正确读取完整的文件列表。在这种情况下,你可能需要发送额外的命令(如q
)来退出分页器。 -
权限:确保你有足够的权限来访问目标目录和列出其中的文件。
-
硬编码凭据:在脚本中硬编码用户名和密码是不安全的做法。你应该考虑使用更安全的方法来管理凭据,如环境变量、配置文件或密钥管理系统。
tn.write(username.encode(‘ascii’) + b’\r\n’) 这句话中,username.encode(‘ascii’) 是什么意思,为什么要这样做, b’\r\n’ 是什么意思,什么作用
在 Python 中,username.encode('ascii')
和 b'\r\n'
分别涉及到字符串的编码和换行符的表示。
username.encode('ascii')
username
是一个字符串(str
类型)。.encode('ascii')
方法将这个字符串编码为 ASCII 格式的字节串(bytes
类型)。- ASCII 编码是一种字符编码标准,用于文本文件的电子交换,它包含了英文字母、数字和一些特殊符号。
- 在与一些网络协议(如 Telnet)交互时,需要发送字节串而不是字符串,因为网络传输的是二进制数据。
- 使用 ASCII 编码是因为 Telnet 协议通常用于与基于文本的旧系统交互,这些系统可能只支持 ASCII 字符集。
b'\r\n'
b'\r\n'
是一个字节串,表示回车(\r
)和换行(\n
)字符的组合。- 在 Windows 系统中,文本文件的行结束符通常是回车加换行(
\r\n
)。 - 在 Unix/Linux 系统中,行结束符通常是换行(
\n
)。 - 在与远程系统交互时(尤其是通过像 Telnet 这样的终端协议),发送回车和换行通常表示命令的结束,并提示远程系统执行该命令。
- 字节串前的
b
前缀表示这是一个字节串字面量,与.encode()
方法返回的字节串类型相同。
为什么要这样做?
- 编码:将字符串编码为字节串是因为网络协议要求发送二进制数据。
- 换行符:发送回车和换行是因为这是许多远程终端系统(包括基于 Unix 和 Windows 的系统)识别命令结束并执行它的方式。
示例中的用途
在示例代码中,tn.write(username.encode('ascii') + b'\r\n')
这行代码的作用是:
- 将用户名
username
编码为 ASCII 字节串。 - 将编码后的用户名与回车换行符
b'\r\n'
连接起来,形成一个完整的命令输入(包括结束符)。 - 通过
tn.write()
方法将这个字节串发送到远程 Telnet 服务器。
这样做是为了模拟用户在 Telnet 会话中输入用户名并按下回车键的行为。
在 Python 中,你可以使用 time.sleep(5)
来暂停程序执行 5 秒钟,这在你需要等待某个外部事件或延迟执行时非常有用。然而,在使用 telnetlib
与远程服务器交互时,简单地等待几秒钟可能不是最佳做法,因为这样做无法确保远程服务器已经完成了你请求的操作并返回了结果。
不过,如果你确定远程服务器的响应时间足够长,以至于可以在等待几秒钟后安全地读取输出,你可以将 time.sleep(5)
插入到你的代码中。这里是一个修改后的示例,展示了如何在发送命令后等待 5 秒钟,然后读取并打印返回的信息:
import telnetlib
import time
# 远程服务器的地址和端口号
host = 'your_remote_server_ip'
port = 23 # Telnet 默认端口
# 用户名和密码
username = 'your_username'
password = 'your_password' # 请注意,在脚本中硬编码密码是不安全的做法
# 要执行的命令
command = 'ls' # 假设你想列出当前目录下的文件
# 创建 Telnet 连接对象
tn = telnetlib.Telnet(host, port, timeout=10) # 设置超时时间为 10 秒
try:
# 登录过程(省略,假设已经成功登录)
# ...
# 登录成功后,代码继续执行
# 发送命令
tn.write((command + '\r\n').encode('ascii'))
# 等待几秒钟(这不是最佳实践,但在这个例子中我们这样做)
time.sleep(5)
# 读取返回的信息
# 注意:这里我们假设输出不会太长,并且没有分页器干扰
# 在实际使用中,你可能需要更复杂的逻辑来处理输出
output = tn.read_very_eager().decode('ascii', errors='ignore') # 使用 read_very_eager 尝试立即读取,但可能不完整
# 或者使用 read_some() 或 read_all() 根据需要读取更多或全部数据
# 但请注意,read_all() 可能会阻塞直到连接关闭,所以通常不是最佳选择
# 如果输出是分页的,你可能需要发送额外的命令(如 'q')来退出分页器
# 打印返回的信息
print(output)
finally:
# 关闭连接
tn.close()
重要注意事项:
time.sleep(5)
简单地暂停了程序的执行,但它不会检查远程服务器是否已经完成了操作。如果远程服务器响应更快或更慢,这种方法可能会导致问题。tn.read_very_eager()
尝试读取任何可用的数据,但不阻塞。然而,它可能不会返回完整的输出,特别是如果输出是在等待期间逐渐生成的。tn.read_some()
可以读取一些数据(默认是 1 个字符),但你可以指定一个更大的数量。这同样不会保证读取到完整的输出。tn.read_until(...)
和tn.read_all()
会阻塞直到满足条件或连接关闭。在使用这些方法时,你需要确保提供的条件能够准确反映你期望的输出结束。- 在处理分页输出时,你可能需要发送额外的命令来退出分页器(如
q
),这取决于远程服务器的配置。 - 硬编码的等待时间(如
time.sleep(5)
)通常不是处理网络交互的最佳方法,因为它无法适应不同的网络延迟或服务器响应时间。更好的方法是实现某种形式的同步或轮询机制,以检查输出是否已准备好被读取。然而,这通常更加复杂,并且可能需要更深入地了解远程系统的行为。
可以使用Python或Linux命令将a.txt
按行分割为8个文件。以下是两种方法:
三,把一个文件的内容行数,分成8份。
方法1:Python脚本
with open('a.txt', 'r') as f:
lines = f.readlines()
total = len(lines)
n = 8
chunk_size = total // n
remainder = total % n
start = 0
for i in range(n):
end = start + chunk_size + (1 if i < remainder else 0)
filename = f'a_{i+1:02d}.txt'
with open(filename, 'w') as out:
out.writelines(lines[start:end])
start = end
执行步骤:
- 将代码保存为
split.py
。 - 在终端运行:
python3 split.py
。 - 生成文件:
a_01.txt
到a_08.txt
。
方法2:Linux命令(Bash脚本)
total=$(wc -l < a.txt)
n=8
chunk=$((total / n))
remainder=$((total % n))
current=1
for i in $(seq 1 $n); do
if [ $i -le $remainder ]; then
lines=$((chunk + 1))
else
lines=$chunk
fi
end=$((current + lines - 1))
sed -n "${current},${end}p" a.txt > "a_$(printf "%02d" $i).txt"
current=$((end + 1))
done
执行步骤:
- 将脚本保存为
split.sh
。 - 赋予执行权限:
chmod +x split.sh
。 - 运行脚本:
./split.sh
。 - 生成文件:
a_01.txt
到a_08.txt
。
原理解释
- 总行数计算:读取文件总行数,按8份均分。
- 余数处理:前
余数
个文件会多1行(确保均匀分布)。 - 生成文件名:使用两位数字编号(如
01
、02
)。
两种方法均能高效完成任务,Python适合大文件,Bash脚本适合快速命令行操作。