有时候需要从别的服务器上下载文件,这时候就可以使用 scp 命令。或者上传文件到别的服务器上

# 如果是传一整个文件的夹的话,需要加上 -r 参数
  • -r:递归复制整个目录。
  • -P <port>:指定远程主机的 SSH 端口,默认为 22。
  • -v:显示详细的调试信息。
  • -p:保留源文件的修改时间、访问时间和权限。
  • -q:安静模式,不显示传输过程的进度信息。
  • -C:开启压缩传输,加快文件传输速度。
  • -i <identity_file>:指定用于身份验证的私钥文件。
  • -l <limit>:限制传输速率,以 Kbps 为单位。
# 本机上传到别的服务器上
scp -P 600 \
    -i id_rsa_pc \
    -r ck-225 \
    pc@xx.xx.xx.xx:/home/pc/

这里我们就是需要把 ck-225 这个文件夹上传到IP为 xx.xx.xx.xx 的服务器上, 地址为 /home/pc/ 下, 用户为 pc, 因为端口是自定义的, 因此需要加上 -P 600 参数, 而且需要指定私钥文件, 因此需要加上 -i id_rsa_pc 参数

使用 python 上传

严谨一点应该是 Windows 文件上传到 Linux 服务器

因为尝试了一下,不知道为什么总有些文件上传的时候会上传丢了,百思不得其解, 就是部分文件总是上传不上去, 因此采用了个笨办法, 就是用 Python 一个文件一个文件的上传

import os
import paramiko

def scp_upload(local_path, remote_path, server, username, private_key_path):
    # 创建SSH客户端
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    try:
        # 读取SSH密钥文件
        private_key = paramiko.RSAKey.from_private_key_file(private_key_path)

        # 连接服务器
        ssh_client.connect(hostname=server, username=username, pkey=private_key)

        # 创建SCP客户端
        scp_client = ssh_client.open_sftp()

        # 递归遍历本地文件夹
        for root, dirs, files in os.walk(local_path):
            for dir in dirs:
                local_dir = os.path.join(root, dir)
                // 这里是去掉了本地路径,然后拼接上远程路径,这样就可以得到远程路径了
                remote_dir = os.path.normpath(os.path.join(remote_path, os.path.relpath(local_dir, local_path))).replace("\\", "/")
                print(f"Creating remote directory {remote_dir}")
                ssh_client.exec_command(f"mkdir -p {remote_dir}")

            for file in files:
                local_file = os.path.join(root, file)
                // 这里做了一个路径替换是因为很抽象,Windows  Linux 的路径分隔符不一样,因此需要替换一下
                remote_file = os.path.normpath(os.path.join(remote_path, os.path.relpath(local_file, local_path))).replace("\\", "/")
                print(f"Uploading {local_file} to {remote_file}")
                scp_client.put(local_file, remote_file)

        # 关闭SCP客户端
        scp_client.close()
    finally:
        # 关闭SSH客户端
        ssh_client.close()

# 调用scp_upload函数进行上传
local_path = r"你要上传的文件夹的路径,会上传这个文件内的所有文件,但是不包括当前这个文件夹,比如写C:\Users\Administrator\IdeaProjects,这样就会把 IdeaProjects 文件夹内的所有文件上传到服务器上,但是不包括 IdeaProjects 这个文件夹本身"
remote_path = "要上传的 Linux 的文件路径,比如/home/user/projects, 这样就会把 IdeaProjects 文件夹内的所有文件上传到服务器上的 /home/user/projects 文件夹里了"
server = "服务器IP地址"
username = "用户名"

private_key_path = r"你的私钥路径"

scp_upload(local_path, remote_path, server, username, private_key_path)

然后这里要注意一点 paramiko 的版本需要高一点, 我用的是 3.4.0, 之前用 2.8.0 会报错. 可能是因为一些参数的不一样, 但是这个不重要, 所以就不细探究了.

Rsync

发现有时候需要上传完成后删除本地的文件,因此此时可以使用这个命令

rsync -avzP --remove-source-files  -e "ssh -i id_rsa" folder username@IP:/remote/to/path/
  • -a:归档模式,表示递归传输文件,并保持所有文件属性。
  • -v:详细模式,输出传输过程中的详细信息。
  • -z:压缩传输,加快文件传输速度。
  • -P:显示传输进度信息。就是显示速度啥的
  • --remove-source-files:传输完成后删除源文件。
  • folder: 本地的文件夹, 你看这里没有 / 结尾
  • username: 用户名
  • IP: 服务器IP地址
  • /remote/to/path/: 服务器上的路径
  • -e "ssh -i id_rsa": 指定私钥文件登录

传过去就会是 /remote/to/path/folder 这个形式