简体   繁体   English

是否可以在 Python 中使用 SCP 从目录传输文件但忽略隐藏文件或符号链接?

[英]Is it possible to transfer files from a directory using SCP in Python but ignore hidden files or sym links?

I'm currently utilising Paramiko and SCPClient in Python to transfer a directory from one server to another as a means of backup.我目前正在使用 Python 中的 Paramiko 和 SCPClient 将目录从一台服务器传输到另一台服务器作为备份。 This works well however I do not want it to copy hidden files (.file_name) or symbolic links.这很有效,但是我不希望它复制隐藏文件 (.file_name) 或符号链接。 Is this possible?这可能吗?

Unfortunately rsync isn't an option for me as it's not available on either of the remote servers I connect to.不幸的是 rsync 不是我的选择,因为它在我连接的任何一个远程服务器上都不可用。 My script is below (sensitive info replaced with dummy data).我的脚本如下(敏感信息替换为虚拟数据)。 Note I need to connect to a jump host before being able to connect to target_1 or target_2.注意我需要先连接到跳转主机,然后才能连接到 target_1 或 target_2。

import os
import shutil
import time
import paramiko
from scp import SCPClient

#set up ssh variables
j_host = '00.00.00.00'
target_host_1 = '00.00.00.001'
target_host_2 = '00.00.00.002'
port_no = 22
username = ''
passw = ''

#set up temporary folder on local machine to store files
path = "/local_path/"
os.mkdir(path)

#create SSH Client for jump server
jump_host=paramiko.SSHClient()
jump_host.set_missing_host_key_policy(paramiko.AutoAddPolicy())
jump_host.connect(j_host, username=username, password=passw)

#set up channel to connect to 1 via jump server
jump_host_transport_1 = jump_host.get_transport()
src_addr = (j_host, port_no)
dest_addr_1 = (target_host_1, port_no)
jump_host_channel_1 = jump_host_transport_1.open_channel("direct-tcpip", dest_addr_1, src_addr)

#set up channel to connect to 2 via jump server
jump_host_transport_2 = jump_host.get_transport()
dest_addr_2 = (target_host_2, port_no)
jump_host_channel_2 = jump_host_transport_2.open_channel("direct-tcpip", dest_addr_2, src_addr)

#function which sets up target server, either 1 or 2
def create_SSHClient(server, port, user, password, sock):
    target=paramiko.SSHClient()
    target.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    target.connect(server, port, user, password, sock=sock)
    return target

#invoke above function to set up connections for 1 & 2
ssh_1 = create_SSHClient(target_host_1, port_no, username, passw, jump_host_channel_1)
ssh_2 = create_SSHClient(target_host_2, port_no, username, passw, jump_host_channel_2)

#delete old files in backup folder
command = "rm -rf /filepath/{*,.*}"
stdin, stdout, stderr = ssh_2.exec_command(command)
lines = stdout.readlines()
#print(lines)

#pause to ensure old directory is cleared
time.sleep(5)

#SCPCLient takes a paramiko transport as an argument, sets up file transfer connection
scp_1 = SCPClient(ssh_1.get_transport())
scp_2 = SCPClient(ssh_2.get_transport())

#get files from 1, store on local machine, put on 2
scp_1.get('/filepath/.', '/target_folder_local/', recursive=True)
scp_2.put('/target_folder_local/.', '/filepath/', recursive=True)

#remove temporary folder
shutil.rmtree(path)

#close connections
ssh_1.close()
ssh_2.close()
jump_host.close()

There's no API in SCPClient to skip hidden file or symbolic links. SCPClient没有用于跳过隐藏文件或符号链接的 API。

But it's easy, if you copy the SCPClient 's code and modify it as you need.但是这很容易,如果您复制SCPClient的代码并根据需要修改它。 See the os.walk loop in _send_recursive function.请参阅_send_recursive函数中的os.walk循环。


If you do not want to modify the SCPClient 's code, you will have to iterate the files on your own, calling SCPClient.put for each.如果您不想修改SCPClient的代码,则必须自己迭代文件,为每个文件调用SCPClient.put It will be somewhat less efficient, as it will start SCP server for each file.它的效率会有所降低,因为它会为每个文件启动 SCP 服务器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM