Python命令行参数输入parser.add_argument()附实例取证应用程序

        1、在编写命令行执行的Python文件时出现:ValueError: mutually exclusive arguments must be optional

        不要采用这种写法:

group=parser.add_mutually_exclusive_group(required=True)
group.add_argument('--md5',help='specifies MD5 algorithm',action='store_true',default=True)

        按照这样来写(建议required都为False,在后续自写判断可以避免执行其他查询操作造成的报错!):

parser=argparse.ArgumentParser("python file system hashing ..filehash")
parser.add_argument('-v','-verbose',help='allows progress messages to be displayed',action='store_true')
parser.add_argument('--md5',help='specifies MD5 algorithm',action='store_false')
parser.add_argument('--sha512', help='specifies SHA512 algorithm', action='store_true',default=False)
parser.add_argument('--sha256', help='specifies SHA256 algorithm', action='store_true',default=False)
#可以在-d简称后跟文件路径,也可以在--reportPath全程后跟文件路径
parser.add_argument('-d', '--rootPath', required=True,type=ValidateDirectoryRead,help='specify the root path for hashing')
parser.add_argument('-r', '--reportPath',required=False, type=ValidateDirectoryWrite, help='specify the path for reports and logs will be written')

gl_args=parser.parse_args()
print(gl_args)
    '-v','-verbose'前面一个是简称,后面的是全称
    default为在输入为空时的默认值
    required设置这个参数是否必须输入
    type可以跟一个函数或者限定的字符类型(int)用于对输入参数进行判断限制
    action跟一个参数,当action=‘store_true’时,默认为FALSE;当action='store_flase'时,默认为TRUE
    通过gl_args=parser.parse_args()来获取参数
    2、对parser.parse_args()参数进行更新操作,gl_args=parser.parse_args(args=['--rootPath','E:\\Temp\\']),下面是可以对参数进行更新的完整代码。
import  argparse
import os,sys

def ValidateDirectoryRead(FileDir):
    """
    读取文件路径判断
    :param FileDir:
    :return:
    """
    print("*********")
    if not os.path.isdir(FileDir):
        raise argparse.ArgumentError("Directory does not exist")
    if os.access(FileDir,os.R_OK):
        return FileDir
    else:
        raise argparse.ArgumentError("Directory is not readable")


def ValidateDirectoryWrite(FileDir):
    """
    写入文件路径判断
    :param FileDir:
    :return:
    """
    if not os.path.isdir(FileDir):
        raise argparse.ArgumentError("Directory does not exist")
    if os.access(FileDir, os.W_OK):
        return FileDir
    else:
        raise argparse.ArgumentError("Directory is not writeable")

parser = argparse.ArgumentParser("python file system hashing ..filehash")
parser.add_argument('-v', '--verbose', action='store_true', help='FileHash Version!')
# 指定在--md5后跟一个输入
parser.add_argument('--md5', help='specifies MD5 algorithm', action='store_false')
parser.add_argument('--sha512', help='specifies SHA512 algorithm', action='store_true', default=False)
parser.add_argument('--sha256', help='specifies SHA256 algorithm', action='store_true', default=False)
# 可以在-d简称后跟文件路径,也可以在--reportPath全程后跟文件路径
parser.add_argument('-d', '--rootPath', required=False, type=ValidateDirectoryRead,
                    help='specify the root path for hashing')
parser.add_argument('-r', '--reportPath', required=False, type=ValidateDirectoryWrite,
                    help='specify the path for reports and logs will be written')

gl_args = parser.parse_args()
if gl_args.verbose:  # 如果只是查询版本信息则返回版本信息化直接退出
    print("FileHash Version 1.0")
    sys.exit()
if gl_args.rootPath == None:
    print("Please enter the path of the file to be processed!")
    sys.exit()
if gl_args.reportPath == None:  # 如果没有输出目录则获取当前目录并创建输出目录到HashOut
    path = os.getcwd()
    try:
        os.makedirs(path + "\\HashOut\\")
    except:
        pass
    # 更具获取的当前文件执行路径对reportPath默认参数进行更新
    tmprootPath = gl_args.rootPath
    gl_args = parser.parse_args(args=['--reportPath', path + "\\HashOut\\", '--rootPath', tmprootPath])
print(gl_args)
print(os.listdir(gl_args.rootPath))
if gl_args.md5:
    gl_hashType = "MD5"
elif gl_args.sha256:
    gl_hashType = "SHA256"
elif gl_args.sha512:
    gl_hashType = "SHA512"
else:
    gl_hashType = "Unknown"
    # logging.error("Unknown Hash Type Specified")
    sys.exit()

Python命令行参数输入parser.add_argument()附实例取证应用程序_第1张图片

         3、通过argparse可以实现通过命令行进行参数输入,以便于无界面执行,下面附上在Python3下可执行的完整代码,文件hash取证,文件的创建及修改信息等,保护两个.py文件,放在同一个文件夹下,cmd下运行FileHashRun.py即可,python FileHashRun.py -h查看帮助命令。

Python命令行参数输入parser.add_argument()附实例取证应用程序_第2张图片

        FileHashRun.py

#!/usr/bin/env python
#-*- coding:utf-8 -*-
# @Time   :  2020/9/15 18:51
# @Author :  singweek
# @File   :  FileHashRun.py


import logging
import time
import sys
import FileHash

if __name__=='__main__':
    logging.basicConfig(filename="FileHashLog.log",level=logging.DEBUG,format='%(asctime)s %(message)s')
    FileHash.ParseCommandLine()
    startTime=time.time()
    logging.info('System:'+sys.platform)
    logging.info('Version:'+sys.version)
    """主要工作函数"""
    filesProcessed=FileHash.WalkPath()
    endTime=time.time()
    duration=endTime-startTime
    logging.info("Files Processed:"+str(filesProcessed))
    logging.info("Elapsed Time:"+str(duration)+'seconds')
    logging.info('')
    logging.info("Program Terminated Normally")
    logging.info('')
    FileHash.DisplayMessage("Program End")

        FileHash.py

#!/usr/bin/env python
#-*- coding:utf-8 -*-
# @Time   :  2020/9/15 18:54
# @Author :  singweek
# @File   :  FileHash.py

import os
import stat
import time
import hashlib
import csv
import argparse
import logging
import sys

#日志文件导入
log=logging.getLogger('main.FileHashRun')

def ParseCommandLine():
    """
    命令行基本参数输入设置,可以在此基础上根据自己的需要设置输入不同的参数
    :return:
    """
    parser=argparse.ArgumentParser("python file system hashing ..filehash")
    parser.add_argument('-v','--verbose', action='store_true',help='FileHash Version!')
    # 指定在--md5后跟一个输入
    parser.add_argument('-md5','--md5', help='specifies MD5 algorithm', action='store_false')
    parser.add_argument('-sha512','--sha512', help='specifies SHA512 algorithm', action='store_true', default=False)
    parser.add_argument('-sha256','--sha256', help='specifies SHA256 algorithm', action='store_true', default=False)
    # 可以在-d简称后跟文件路径,也可以在--reportPath全程后跟文件路径
    parser.add_argument('-d', '--rootPath',required=False,type=ValidateDirectoryRead,help='specify the root path for hashing')
    parser.add_argument('-r', '--reportPath',required=False,type=ValidateDirectoryWrite,help='specify the path for reports and logs will be written')
    global gl_args
    global gl_hashType
    gl_args=parser.parse_args()
    if gl_args.verbose:#如果只是查询版本信息则返回版本信息化直接退出
        print("FileHash Version 1.0")
        sys.exit()
    if gl_args.rootPath==None:
        print("Please enter the path of the file to be processed!")
        sys.exit()
    if gl_args.reportPath==None:#如果没有输出目录则获取当前目录并创建输出目录到HashOut
        path = os.getcwd()
        try:
            os.makedirs(path + "\\HashOut\\")
        except:
            pass
        #更具获取的当前文件执行路径对reportPath默认参数进行更新
        tmprootPath=gl_args.rootPath
        gl_args = parser.parse_args(args=['--reportPath', path + "\\HashOut\\",'--rootPath',tmprootPath])

    if gl_args.md5:
        gl_hashType="MD5"
    elif gl_args.sha256:
        gl_hashType="SHA256"
    elif gl_args.sha512:
        gl_hashType="SHA512"
    else:
        gl_hashType="Unknown"
        logging.error("Unknown Hash Type Specified")
        sys.exit()

    DisplayMessage("Command line processed: Successfully")
    return

class CSVWrite:
    """
    利用CSV对获取到的取证数据进行存储
    """
    def __init__(self,FileName,hashType):
        try:
            self.csvFile=open(FileName,'w')
            self.write=csv.writer(self.csvFile,delimiter=',',quoting=csv.QUOTE_ALL)
            self.write.writerow(('File','Path','Size','Modified Time','Access Time','Created Time',hashType,'Owner','Group','Mode'))
        except:
            log.error("CSV File Failure")
    def WriteRow(self,filename,filepath,filesize,mtime,atime,ctime,hashwal,own,grp,mod):
        self.write.writerow((filename,filepath,filesize,mtime,atime,ctime,hashwal,own,grp,mod))

    def WriteClose(self):
        self.csvFile.close()

def ValidateDirectoryRead(FileDir):
    """
    读取文件路径判断
    :param FileDir:
    :return:
    """
    if not os.path.isdir(FileDir):
        raise argparse.ArgumentError("Directory does not exist")
    if os.access(FileDir,os.R_OK):
        return FileDir
    else:
        raise argparse.ArgumentError("Directory is not readable")


def ValidateDirectoryWrite(FileDir):
    """
    写入文件路径判断
    :param FileDir:
    :return:
    """
    if not os.path.isdir(FileDir):
        raise argparse.ArgumentError("Directory does not exist")
    if os.access(FileDir, os.W_OK):
        return FileDir
    else:
        raise argparse.ArgumentError("Directory is not writeable")

def DisplayMessage(msg):
    """
    信息输出显示
    :param msg:
    :return:
    """
    print(msg)

def HashFile(File,simpleName,csvwrite):
    """
    对单个文件进行hash校验并,默认选择MD5
    :param File:
    :param simpleName:
    :param result:
    :return:
    """
    #判断路径是否存在,在判断路径不是能是链接,最后判断路径是正确的文件路径
    if os.path.exists(File) and not os.path.islink(File) and os.path.isfile(File):
        try:#学习到了try后面还可以跟else之前没有用到的
            f=open(File,'rb')
        except IOError:
            log.warning("Open Failed:" + File)
            return
        else:
            try:
                rd=f.read()
            except IOError:
                f.close()
                log.warning("Read Failed:"+ File)
                return
            else:
                theFileStats=os.stat(File)
                (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)=os.stat(File)
                DisplayMessage("Processing File:"+File)#打印进程文件名
                fileSize=str(size)

                #时间格式转换
                modifiedTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(mtime))
                accessTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(atime))
                createdTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ctime))

                ownerID=str(uid)
                groupID=str(gid)
                fileMode=bin(mode)
                """根据读取的rb文件进行hash值计算获取"""
                if gl_args.sha256:
                    hash=hashlib.sha256()
                    hash.update(rd)
                    hexhash=hash.hexdigest()
                    hashValue=hexhash.upper()
                elif gl_args.sha512:
                    hash=hashlib.sha512()
                    hash.update(rd)
                    hexhash=hash.hexdigest()
                    hashValue=hexhash.upper()
                else:#默认选择
                    hash = hashlib.md5()
                    hash.update(rd)
                    hexhash = hash.hexdigest()
                    hashValue = hexhash.upper()
                # print(simpleName,File,fileSize,modifiedTime,accessTime,createdTime,hashValue,ownerID,groupID,mode)
                csvwrite.WriteRow(simpleName,File,fileSize,modifiedTime,accessTime,createdTime,hashValue,ownerID,groupID,mode)
                return True
    else:
        log.warning("[%s]"%repr(simpleName), ",FilePath Wrong, Please Check Path!")
        return False

def WalkPath():
    """
    对需要取证校验的文件进行读取,并将结果写入文件,返回执行成功和错误文件数
    :return:
    """
    processCount=0
    errorCount=0
    oCSV=CSVWrite(gl_args.reportPath+'fileSystemReport.csv',gl_hashType)#调用CSV存储函数
    log.info('Root Path:'+gl_args.rootPath)
    for root,dirs,files in os.walk(gl_args.rootPath):
        for file in files:
            fname=os.path.join(root,file)
            result=HashFile(fname,file,oCSV)
            if result is True:
                processCount+=1
            else:
                errorCount+=1
    oCSV.WriteClose()
    return (processCount,errorCount)


4、getopt参数输入

import sys,getopt

def Get_Input(argv):
    """参数输入"""
    try:
        opts= getopt.getopt(argv,"srh",['input',"out",'help'])
        print(opts)
    except getopt.GetoptError:
        print('test.py -h 帮助')
        sys.exit(2)
    opt=opts[0][0][0]
    if opt in ("-s"):
        starts = opt
        print("启动参数", starts)
        return starts
    elif opt in ("-r"):
        runs = opt
        print("运行参数",runs)
        return runs
    else:
        print('test.py -s启动浏览器')
        print('test.py -r操作浏览器')
        sys.exit(2)
inputstring=Get_Input(sys.argv[1:])#输入一个参数

你可能感兴趣的:(Python,parse_args参数更新,取证应用程序,文件hash校验,文件取证)