Python ssh进入服务器后需要运行多个md5操作
在ssh进入服务器后,我当前需要对文件运行多个md5操作(>15000)。但是我当前的实现速度非常慢,因为每个md5操作都会创建一个使用exec_命令的新通道。有没有更好的方法使用paramikoPython ssh进入服务器后需要运行多个md5操作,python,ssh,paramiko,Python,Ssh,Paramiko,在ssh进入服务器后,我当前需要对文件运行多个md5操作(>15000)。但是我当前的实现速度非常慢,因为每个md5操作都会创建一个使用exec_命令的新通道。有没有更好的方法使用paramiko def md5(fname): hash_md5 = hashlib.md5() if os.path.isfile(fname): with open(fname, "rb") as f: for chunk in iter(lambda: f
def md5(fname):
hash_md5 = hashlib.md5()
if os.path.isfile(fname):
with open(fname, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
def connect_server(host1):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host1)
return ssh
for files in install_files:
stdin, stdout, stderr = ssh.exec_command('md5 %s' % files)
file_md5_map[file] = stdout.read().split()[0]
只调用一次
exec_命令
(无论有多少文件!)的高性能实现可能如下所示:
remote_script = '''
exec 2>/dev/null ## writes to stderr will block; suppress them.
bash -s <<'EOF'
while IFS= read -r -d '' filename; do
result=$(md5 "$filename");
result=${result%%[[:space:]]*}
printf '%s\t%s\0' "${result}" "${filename}"
done
EOF
'''
stdin, stdout, stderr = ssh.exec_command(remote_script)
writer_thread = threading.Thread(
target = lambda: stdin.write('\0'.join(install_files) + '\0')
)
writer_thread.start()
for datum in stdout.read().split('\0'):
if len(datum) == 0: continue # should only happen for the last line
(md5sum, filename) = datum.split('\t', 1)
file_md5_map[filename] = md5sum
remote_脚本=“”
exec 2>/dev/null##对stderr的写入将被阻止;压制他们。
bash-s一个只调用一次exec\u命令的高性能实现(无论有多少文件!),可能如下所示:
remote_script = '''
exec 2>/dev/null ## writes to stderr will block; suppress them.
bash -s <<'EOF'
while IFS= read -r -d '' filename; do
result=$(md5 "$filename");
result=${result%%[[:space:]]*}
printf '%s\t%s\0' "${result}" "${filename}"
done
EOF
'''
stdin, stdout, stderr = ssh.exec_command(remote_script)
writer_thread = threading.Thread(
target = lambda: stdin.write('\0'.join(install_files) + '\0')
)
writer_thread.start()
for datum in stdout.read().split('\0'):
if len(datum) == 0: continue # should only happen for the last line
(md5sum, filename) = datum.split('\t', 1)
file_md5_map[filename] = md5sum
remote_脚本=“”
exec 2>/dev/null##对stderr的写入将被阻止;压制他们。
bash-s如何计算md5?使用自定义md5函数?为什么不使用命令md5sum
?它速度更快,但计算md5仍然是一个代价高昂的操作。是的,但我注意到实际的md5操作并不昂贵,但ssh.exec_命令被证明是非常耗时的。这可能是由网络延迟引起的。如果可以使用md5sum
,则可以通过md5sum file1 file2 file3…
一次计算多个文件。在这种情况下,您只需要向远程服务器发送一个命令。如果是延迟问题,则无需一次只执行一个exec\u command()
。您可以在同一传输上打开多个通道,而不是等待一个通道完成后再开始下一个通道。当然,你不想一次运行所有的15k,但是保留一个15k的池是一个非常好的主意。也就是说,你现在这样做有一些严重的安全问题。如果您有一个名为/tmp/$(rm-rf~)
(是的,它是一个完全合法的文件名),那么'md5%s'%file
将有非常不希望的副作用。总是(总是!)在将内容替换到命令行之前,使用pipes.quote()
(在Python 2中)或shlex.quote()
(在Python 3中)转义内容。如何计算md5?使用自定义md5函数?为什么不使用命令md5sum
?它速度更快,但计算md5仍然是一个代价高昂的操作。是的,但我注意到实际的md5操作并不昂贵,但ssh.exec_命令被证明是非常耗时的。这可能是由网络延迟引起的。如果可以使用md5sum
,则可以通过md5sum file1 file2 file3…
一次计算多个文件。在这种情况下,您只需要向远程服务器发送一个命令。如果是延迟问题,则无需一次只执行一个exec\u command()
。您可以在同一传输上打开多个通道,而不是等待一个通道完成后再开始下一个通道。当然,你不想一次运行所有的15k,但是保留一个15k的池是一个非常好的主意。也就是说,你现在这样做有一些严重的安全问题。如果您有一个名为/tmp/$(rm-rf~)
(是的,它是一个完全合法的文件名),那么'md5%s'%file
将有非常不希望的副作用。总是(总是!)在将内容替换到命令行之前,使用pipes.quote()
(在Python 2中)或shlex.quote()
(在Python 3中)转义内容。
md5_of_file1<TAB>/path/to/file1<NUL>md5_of_file2<TAB>/path/to/file2<NUL>