1。背景最近接到一个产品请求,定时推送文件数据到指定sftp服务器的指定目录。因为项目组已经有了现成的组件,可以很方便的快速上传文件到sftp服务器,本来是一件容易的事情,但是问题来了,指定sftp服务器指定的密码包含系统关键字和一些特殊字符。导致当前组件在解析时失败。因此重新开发了下面的一套脚本来满足这种特殊的需求。2.代码实现Python代码#test_upload.pyimportos,sysimportyamlfromoptparseimportOptionParserimportparamikoimporttracebackopt_parser=OptionParser()opt_parser.add_option('--node',action='store',type='string',dest='node',help='sftpconfig')opt_parser.add_option('--local_file',action='store',type='string',dest='local_file',help='要传输的文件')defload_config_from_param_conf(key):""":paramkey:指定业务使用的sftp服务名称,如sftp.yaml文件中的key:test_file_upload:return:从指定路径获取yaml文件,读取指定key,返回例如sftp.yaml文件关键是test_file_upload下的配置选项值,包括:host,port,user,password,destination"""config_file=f'{os.environ["TASK_MAIN"]}/test_conf/sftp.yaml'#获取指定路径的yaml文件withopen(config_file,'r')asr:#打开yaml文件内容config=yaml.load(r)#将yaml数据转换成字典returnconfig['sftp']['upload'][key]defupload(sftp_conf,local_file_path):""":paramsftp_conf:获取指定sftp_conf=test_file_upload下返回的字典值,其中参数sftp_conf和load_config_from_param_conf函数中的参数值是一致的:paramlocal_file_path:指定要上传到sftp服务器的本地文件的绝对路径:return:"""sf=paramiko.Transport((sftp_conf['host'],sftp_conf['port']))sf.connect(username=sftp_conf['user'],password=sftp_conf['password'])sftp=paramiko.SFTPClient.from_transport(sf)to_path=sftp_conf['destination']sftp.put(local_file_path,to_path+os.sep+os.path.split(local_file_path)[-1],confirm=False)sftp.close()如果__name__=='__main__':option=opt_parser.parse_args(sys.argv[1:])[0]sftp_conf=load_config_from_param_conf(option.node)try:upload(sftp_conf,option.local_file)除了Exceptionase:print(traceback.format_exc())raiseException('upload{}fileerror.'.format(option.local_file))sftp配置文件code#sftp.yamlsftp:upload:test_file_upload:host:10.12.34.6port:808user:user_testpassword:8Z.Lx/2@UHdestination:/data/dump3.代码分析(1).yaml模块importyamlBefore导入yaml模块,可以使用下面命令安装模块python3-mpipinstallPyYamlyaml此处模块的作用是读取sftp配置文件的代码,将指定key:test_file_upload下的key:value的值转换成字典。例如:load_config_from_param_conf函数中的返回值是使用yaml读取sftp配置文件代码后,返回key:test_file_upload下的配置选项值。格式如下:{"host":"10.12.34.6","port":"808","user":"user_test","password":"8Z.Lx/2@UH","destination":"/data/dump"}最后将返回值作为参数传递给上传函数。(2).OptionParsermodulefromoptparseimportOptionParser按照yaml模块的安装方式,先安装optparse模块,然后在文件opt_parser=OptionParser()opt_parser.add_option('--node',action='store',type='string',dest='node',help='sftpconfig')opt_parser.add_option('--local_file',action='store',type='string',dest='local_file',help='要上传的文件')这里我使用OptionParser类实例化了一个对象:opt_parser,通过对象调用add_option方法添加2个参数,分别是:node,local_file1)。形参:--node,实参:node代表的业务含义是:指定要上传的sftp节点,具体参数值对应sftp配置文件代码中的test_file_upload2)。形参:--local_file,实参:local_file所代表的业务含义是:指定本地需要上传到sftp服务器的具体文件路径3).调用命令python3test_upload.py--nodetest_file_upload--local_file/home/test/sftp_load/test_001.csv4)。add_option()方法add_option()参数说明:action:存储方式,分别为:store、store_false、store_truetype:类型dest:存储的变量default:默认值help:帮助信息参数:action枚举store:参数列表中带--node,则下一个元素将:test_file_upload作为其dest实参节点的值;如果没有--node,则对应节点的值为None;store_true:参数列表中有--local_file,那么dest参数local_file的值为True;否则为默认定义的默认值,这里不给出默认值;store_false:参数列表中有--local_file,则dest参数local_file的值为False;否则为默认定义的默认值,这里不给出默认值;parameter:typetype为指定传入参数的类型,这里的参数类型为stringtypeparameter:destdest为参数传入后存储的是哪个变量,下面代码中对这个参数的引用也是通过定义的变量名来引用这里。参数:defaultdefault与action的值配合使用。当action=store_true,default=123,如果有传入形参--local_file,实参local_file的值为:True当action=store_true,default=123,如果没有传入形参--local_file,实参local_file的值为:123whenaction=store_false,default=123,如果有传入形参--local_file,则实参local_file的值为:falsewhenaction=store_false,default=123,如果未传入形参--local_file,实参local_file的值为:123参数:help相当于帮助文档,用于说明该参数的含义。
