end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

pythonのsubprocessで、リモートサーバにある同一dirとの差分比較(diff)

pythonで、urlの死活監視を行い、NGであれば、sendmail を外部コマンドで通知 - end0tknr's kipple - web写経開発

上記urlと同様かもしれませんが、 localとremoteにあるdirを比較し、ファイル有無やsize差異がある場合、 表示します。

#!/usr/bin/python2
# -*- coding: utf-8 -*-
import getopt
import re
import subprocess
import sys

remote_ip = "xxx.xxx.xxx.xxx"
remote_user = "ないしょユーザ"
private_key = "/home/end0tknr/.ssh/priv_key.pem"

ssh_timeout = 5 #sec

target_dirs = [
    "/path/to/cgi-bin",
    "/path/to/conf",
    "/path/to/web",
]

def main():
    local_files = find_local_files()
    remote_files = find_remote_files()

    result_compare = compare_paths(local_files, remote_files)
    print "\n".join( result_compare )

    
def compare_paths(local_files, remote_files):

    ret_lines = []
    
    reg_exp = re.compile(".*\.(bak|log|~)($|/)")

    for file_path in sorted( local_files.keys() ):
        if reg_exp.match(file_path):
            continue

        disp_cols = [file_path,
                     local_files[file_path]["size"],
                     local_files[file_path]["timestamp"] ]
        # local にのみ fileあり
        if not file_path in remote_files:
            disp_cols.append( "" )
            disp_cols.append( "" )
            disp_cols.append( "ONLY_IN_OLD" )

            ret_lines.append( "\t".join(disp_cols) )
            continue

        disp_cols.append( remote_files[file_path]["size"] )
        disp_cols.append( remote_files[file_path]["timestamp"] )
        if local_files[file_path]["size"] != remote_files[file_path]["size"]:
            disp_cols.append( "SIZE_DIFF" )
            ret_lines.append( "\t".join(disp_cols) )

        del remote_files[file_path]

    for file_path in sorted( remote_files.keys()) :
        if reg_exp.match(file_path):
            continue

        disp_cols = [file_path,
                     "",
                     "",
                     remote_files[file_path]["size"],
                     remote_files[file_path]["timestamp"],
                     "ONLY_IN_NEW"]
        ret_lines.append( "\t".join(disp_cols) )
    return sorted( ret_lines )

        
def find_local_files():

    file_paths = {}
    for target_dir in target_dirs:
        sh_cmd = "find "+ target_dir +" -type f | "+ \
            " xargs ls -l --time-style='+%Y-%m-%dT%H:%M:%S'"

        proc = subprocess.Popen(
            sh_cmd,
            shell  = True,
            stdin  = subprocess.PIPE,
            stdout = subprocess.PIPE,
            stderr = subprocess.PIPE)
        stdout, stderr = proc.communicate()
        
        for line in stdout.splitlines():
#        for line in stdout.decode().splitlines():
            try:
                line = line.decode('utf-8')
            except:
                continue
            cols = re.split( '\s+', line.strip() )

            if len(cols) < 7:
                continue

            file_paths[ cols[6] ] = { "size"     : cols[4],
                                      "timestamp": cols[5] }
    return file_paths

def find_remote_files():

    file_paths = {}
    target_dirs_str = " ".join(target_dirs)

    ssh_cmd = \
        "ssh -i " + private_key + " "+\
        remote_user + "@" + remote_ip + " "+\
        "/home/users/omng-him01/script/find_files.py "+ target_dirs_str
 
    proc = subprocess.Popen(
        ssh_cmd,
        shell  = True,
        stdin  = subprocess.PIPE,
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE)
    stdout, stderr = proc.communicate()
        
    for line in stdout.splitlines():
#    for line in stdout.decode().splitlines():
        try:
            line = line.decode('utf-8')
        except:
            continue

        cols = re.split( '\s+', line.strip() )
        if len(cols) < 7:
            continue

        file_paths[ cols[6] ] = { "size"     : cols[4],
                                  "timestamp": cols[5] }
    return file_paths


if __name__ == '__main__':
    main()