1 说明

实现功能:

  扫描指定文件目录下文件,通过scp上传到指定服务器目录下

程序结构简单说明:

  • 包含两个线程,线程一:扫描文件线程;线程二:消费文件线程;
  • 线程一:扫描指定文件目录下文件,把符合要求的文件名加入到全局列表中;
  • 线程二:遍历全局列表,取出文件名,并获取该文件最后修改时间;
  • 判断文件最后修改时间与当前时间只差是否大于阈值;
  • 如果大于阈值则通过scp上传文件到指定服务器,上传成功删除文件并从全局列表中移除。

 

2 SSH免密登录环境

  因为是通过scp自动上传,无需人工干预,所以需要配置两台服务的ssh免密登录;

  假如本次服务器分别为A和B,A上传文件到B,按照如下步骤配置ssh免密登录环境:



1)在A机下生成公钥/私钥对。

  [root@A ~]# ssh-keygen -t rsa -P ''


  -P表示密码,-P '' 就表示空密码,也可以不用-P参数,这样就要三车回车,用-P就一次回车。



  该命令将在/root/.ssh目录下面产生一对密钥id_rsa和id_rsa.pub。



  一般采用的ssh的rsa密钥:



  id_rsa     私钥



  id_rsa.pub 公钥



 



  下述命令产生不同类型的密钥



ssh-keygen -t dsa 
  
 
  

      ssh-keygen -t rsa 
  
 
  

      ssh-keygen -t rsa1


 



2)把A机下的/root/.ssh/id_rsa.pub 复制到B机的 /root/.ssh/authorized_keys文件里,先要在B机上创建好 /root/.ssh 这个目录,用scp复制。



[root@A ~]# scp /root/.ssh/id_rsa.pub root@192.168.1.181:/root/.ssh/authorized_keys 
  
 
  
 
     root@192.168.1.181's password: 
  
 
  

      id_rsa.pub                                    100%  223     0.2KB/s   00:00


 



  由于还没有免密码登录的,所以要输入一次B机的root密码。



 



3)authorized_keys的权限要是600


[root@B ~]# chmod 600 /root/.ssh/authorized_keys



 



4)A机登录B机


[root@A ~]# ssh -l root 192.168.1.181 
  
 
  
 
     The authenticity of host '192.168.1.181 (192.168.1.181)' can't be established. 
  
 
  
 
     RSA key fingerprint is 00:a6:a8:87:eb:c7:40:10:39:cc:a0:eb:50:d9:6a:5b. 
  
 
  
 
     Are you sure you want to continue connecting (yes/no)? yes 
  
 
  
 
     Warning: Permanently added '192.168.1.181' (RSA) to the list of known hosts. 
  
 
  

      Last login: Thu Jul  3 09:53:18 2008 from root 
  
 
  
 
     [root@B ~]#


 



  第一次登录是时要你输入yes。



 



  现在A机可以无密码登录B机了。



 



  想让A,B机无密码互登录,那B机以上面同样的方式配置即可。



 

3 python源码



#coding=utf-8
"""
作用说明:
通过scp上传文件,需要两台无服务预先配置好ssh无密登录,至于如何配置
可以网上查看教程。
线程一:扫描指定文件目录下的文件,并添加到全局列表中
线程二:扫描全局列表,把文件上传到指定的服务器中,
        上传成功则删除该文件,并从全局列表中移除
"""


from threading import Thread, Lock
import signal
import time
import datetime
import os
import sys


ftp_list = []                         # 全局列表
flag_time = 5                         # 时间阈值,表示当前时间戳与文件最后修改时间大于该值时才操作
ftp_path="/tmp/data"                  # 示例:要扫描的文件目录
server=" root@192.168.101.22:/data/"  # 示例:上传到服务器的文件目录


"""
path:要扫描的文件目录
file_list: 将扫描到文件加入该列表中
key: 扫描文件时,有的文件不需要,以key关键词
      判断该文件是否为需要的文件
"""
def get_file_list(path, file_list, key):
    files=os.listdir(path)
    for f in files:
        if key not in f:
            continue
        file_with_path = path+"/"+f
        if file_with_path in file_list:
            continue
        if not os.path.isdir(file_with_path):
            try:
                time_str = os.path.getmtime(file_with_path)
                file_time = int(time_str)
                now_time = int(time.time())
                #print("time :", now_time-file_time)
            except OSError as err:
                continue
            if((now_time-file_time) > flag_time):
                lock.acquire()
                file_list.append(file_with_path)
                lock.release()
                #print("[## add ##]add file %s to global list"% file_with_path)

"""
file_list: 扫描文件列表,并把文件上传到服务器,
           上传成功后,删除文件,并从全局列表中移除
"""
def send_file(file_list):
    year = datetime.datetime.now().year
    month = datetime.datetime.now().month
    day = datetime.datetime.now().day
    for f in file_list:
        if f.strip():
        		#上传到服务指定目录下子目录以 年月日 分类
            shell_cmd="scp "+f+server+"/"+str(year)+"/"+str(month)+"/"+str(day)
            ret_shell=os.system(shell_cmd)
            #print("shellcmd:",shell_cmd)
            lock.acquire()
            file_list.remove(f)
            lock.release()
            os.remove(f)
            #print("[-- remove --]remove file %s "% f)


def quit(signum, frame):
    print("You choose to stop me")
    sys.exit()


"""
线程一:扫描文件目录,将符合要求文件名添加到全局列表中
"""
def traverse_dir():
    global ftp_list
    while True:
        get_file_list(ftp_path, ftp_list, ".bin")
        time.sleep(2)
        #print("======================== start to traverse ===========================");
        #print("[traverse]:%s"% ftp_list)


"""
线程二:扫描全局列表,将文件上传到指定服务器,
        上传成功,删除文件,并从全局列表中移除
"""
def consume_file():
    global ftp_list
    while True:
        send_file(ftp_list)
        time.sleep(2)
        #print("consume:%s"%ftp_list)



if __name__=='__main__':
    try:
        signal.signal(signal.SIGINT, quit)
        signal.signal(signal.SIGTERM, quit)

        lock = Lock()   #创建线程锁
        thread_product = Thread(target=traverse_dir)
        thread_consume = Thread(target=consume_file)
        thread_product.setDaemon(True)
        thread_product.start()
        thread_consume.setDaemon(True)
        thread_consume.start()

        while True:
            pass
    except Exception, exc:
        print exc