• 从Windows备份文件到Linux服务器


    各种深坑

    尝试1—FTP

    因为组内有FTP服务器,所以尝试用bat编写把文件压缩后放到FTP上。其中压缩使用7zip.exe来完成,定时任务使用windows自带的定时任务。

    整个脚本过程实现比较简单,大致如下

    @echo off
    
    set ftpfilename=autoftp.cfg
    echo open ftp_ip > "ftpfilename"
    echo user_name >>"ftpfilename"
    echo passwd >>"ftpfilename"
    
    echo bin >>"ftpfilename"
    echo cd bak >>"ftpfilename"
    echo put file_name >>"ftpfilename"
    
    echo bye>>"ftpfilename"
    Pause
    

    可做完了发现,自己电脑上可以执行,但在那台win服务器上无法连接FTP…搞半天发现失公司网络策略问题,只能放弃

    尝试2—尝试使用VBS调用SCP

    FTP失败了,又没有其他的文件服务器,就尝试使用scp拷贝到其他服务器。

    于是尝试使用VBS调用cmd来实现,过程需要输入密码,于是调用sendkeys这种函数。

    整个过程大概如下:

    Dim FileName
    Filename = year(Now)&Month(Now)&day(Now)&"_"&hour(Now)&Minute(Now)
    
    Dim WshShell
    Set WshShell = Wscript.CreateObject("WScript.Shell")
    WshShell.Run "cmd.exe"
    WScript.Sleep 1000
    Wscript.AppActive "C:\Windows\System32\cmd.exe"
    WshShell.SendKeys "+"   
    
    WshShell.SendKeys """"
    WshShell.SendKeys "C:\Program Files\7-Zip\7z.exe"
    WshShell.SendKeys """"
    
    WshShell.SendKeys " "
    WshShell.SendKeys "a"
    WshShell.SendKeys ""
    WshShell.SendKeys "-r"
    WshShell.SendKeys " "
    
    WshShell.SendKeys """"
    WshShell.SendKeys "C:\Users\Administrator\Desktop\bak\" & FileName & ".zip"
    WshShell.SendKeys """"
    
    WshShell.SendKeys """"
    WshShell.SendKeys "C:\ProgramData\Jenkins\.jenkins\"
    WshShell.SendKeys """"
    
    WshShell.SendKeys "{ENTER}"
    
    WshShell.SendKeys """"
    WshShell.SendKeys "C:\Users\Administrator\Desktop\pscp.exe"
    WshShell.SendKeys """"
    WshShell.SendKeys " "
    WshShell.SendKeys "C:\Users\Administrator\Desktop\bak\" & FileName & ".zip"
    WshShell.SendKeys " "
    WslShell.SendKeys "xxx@xxx:/yyy/yyy"
    WshShell.SendKeys "{ENTER}"
    
    WshShell.SendKeys "password"
    WshShell.SendKeys "{ENTER}"
    
    WshShell.SendKeys "exit"
    WshShell.SendKeys "{ENTER}"
    

    整体思路就是模拟在cmd中操作的过程,先压缩,再scp走;pscp.exe要自己拷贝到这个环境上。

    写完发现手动执行,可以操作;登录在系统上,定时任务也可以执行成功;

    但,锁屏后,执行就失败了……

    起初以为是cmd窗口不在最前端的原因,后面加了很多激活cmd窗口的操作,发现还是失败。

    尝试3——自己完成定时任务

    尝试把2的代码改了一下,在代码中加入for循环,判断当前时间满足要求后,执行一次备份;如果时间不符合要求,则一小时后再来尝试。

    代码不再赘述,大概逻辑如下

    Do  While True
    	xxxx
      if yyyy Then
    			backup_code
      End if
      Wscript.Sleep 3600000
    Loop
    

    尝试发现,也是手动执行、登录界面内执行没问题;锁屏等定时任务,则执行失败。

    后面查到了原因,是因为锁屏状态下,SendKeys本身就无法执行……于是思路又堵死。

    尝试4——SCP免密

    安装了openssh for windows,却发现免密无法完成。

    生成了密钥,增加了config文件,却一直提示没有权限或者权限错误。按照网上的提示,操作后依然不行。

    可参考

    https://stackoverflow.com/questions/49926386/openssh-windows-bad-owner-or-permissions

    尝试5——换个SCP版本

    想尝试换个版本,查资料的时候,发现有些资料说可以使用Python的paramiko库完成。于是我搜了一下,发现自己内网电脑有这个东西……于是安装上后,再去完成这个功能。

    尝试6——使用Python的paramiko库完成

    起初想的是使用subprocess来调用7zip完成压缩,结果写完代码,总是提示权限错误,如下

    https://stackoverflow.com/questions/41169105/python-7-zip-subprocess-windowserror-error-5-access-is-denied

    搞了半天没成功…只能尝试用zipfile库完成压缩。

    代码大概如下

    import paramiko, zipfile, os
    from datetime import datetime, date, timedelta
    
    des_file = xxx   # 备份生成的文件
    backup_files = yyy   # 需要备份的文件路径
    
    def zip_dir(source_dir, output_file):
        zip = zipfile.ZipFile(output_file, "w", zipfile.ZIP_DEFLATED)
        for path, dirnames, filenames in os.walk(dirpath):
            # 去掉目标跟路径,只对目标文件夹下边的文件及文件夹进行压缩
            fpath = path.replace(source_dir, '')
     
            for filename in filenames:
                zip.write(os.path.join(path, filename), os.path.join(fpath, filename))
        zip.close()
    
    zip_dir(backup_files, des_file)
    
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(ip, port, username, passwd)
    
    # sftp = paramiko.SFTPClient.from_transport(ssh.get_transport())
    sftp = ssh.open_sftp()
    sftp.put(des_file, des_file_path)
    
    older_file = (date.today() - timedelta(days=21)).strftime("%y%m%d")
    stdin, stdout, stderr = ssh.exec_command("rm xxx" + older_file + "*zip")
    
    if sftp:
        sftp.close()
    if ssh:
        ssh.close()
    

    测试,终于完成……

    总结

    不要用windows服务器……

  • 相关阅读:
    Soap 教程
    MAC mysql install
    PHP date
    MAC 终端terminal颜色
    MAC 终端颜色设置
    MAC brew软件安装
    PHP iconv函数
    Java----前端验证之验证码额实现
    Java---Ajax在Struts2框架的应用实例
    Java基础—标识符及命名规范
  • 原文地址:https://www.cnblogs.com/wswang/p/16133725.html
Copyright © 2020-2023  润新知