为何subprocess调用的py中的raise没起作用?

发布于 2022-09-12 22:33:59 字数 3621 浏览 21 评论 0

背景

我有一个脚本A需要通过subprocess在另外一个脚本B中被调用。在脚本A中有一个raise语句来捕获异常【单独运行这个脚本会正常报错】,但脚本B在调用的时候并不会捕获到这个异常,返回状态码依旧是0,不懂为什么?可能哪里我没注意到或者没理解一些原理嘛。。。

部分代码

由于一些原因,代码不能完全展示,我只展示部分...

# A.py
...

def get_rid_lonlat(self):
        need_json_list = self.need_json.split(",")
        print("need_json_list:{}".format(need_json_list))
        # json_data_list: [rid_subid_trajs.json,rid_subid_trajsoverlap.json,spot_json.json]
        json_data_list = []
        for file_name in need_json_list:
            file_path = os.path.join(self.input_road_data, file_name)
            if os.path.exists(file_path):
                json_data = self.read_json(file_path)
                json_data_list.append(json_data)
            else:
                raise FileNotFoundError(file_path)  # raise exception

...
# B.py

import os
import argparse
import subprocess


def run_vis_rid_draw(
    data_name: str, 
    hdmap_path: str, 
    road_path: str, 
    vis_road_path: str, 
    code_abs_path: str = 'A.py'
) -> bool:
    vis_code_abs_path: str = os.path.join(hdmap_path, code_abs_path)
    road_data_name: str = 'Road_{name}'.format(name=data_name)
    road_data_path: str = os.path.join(road_path, road_data_name)
    vis_road_data_path: str = os.path.join(vis_road_path, road_data_name)
    vis_log_path: str = os.path.join(vis_road_data_path, 'road_vis_map.log')
    
    # create vis_road_data_path
    os.makedirs(vis_road_data_path, exist_ok=True)
    
    cmds: list = ['echo', 'xxxxxx', '|', 'sudo', '-S', 'sh', '-c',
                "'python3", vis_code_abs_path, '-i', road_data_path, 
                '-o', vis_road_data_path, '|', 'tee', f"{vis_log_path}'"]
    
    cmds_str: str = " ".join(cmds)
    print('cmd: ', cmds_str)
    return_flag = subprocess.run(cmds_str, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

    if return_flag.returncode:
        print(f'Error: {return_flag.returncode} => {return_flag.stderr.decode()}')
    
    else:
        print(f'Normal: {return_flag.returncode} => {return_flag.stdout.decode()}')


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Execute the task of drawing map.')
    parser.add_argument('-i', '--data_name', help='data name',
                        default="example")
    parser.add_argument('-p', '--hdmap_path', help='hdmap path',
                        default='./')
    parser.add_argument('-r', '--raw_path', help='raw path',
                        default='./')
    parser.add_argument('-w', '--road_path', help='road path',
                        default='./')
    parser.add_argument('-v', '--vis_road_path', help='vis road path',
                        default='./')
    
    args = parser.parse_args()

    run_vis_rid_draw(args.data_name, args.hdmap_path, args.road_path, args.vis_road_path)
错误信息
# A.py

need_json_list:['rid_subid_trajs.json', 'rid_subid_trajsoverlap.json', 'spot_json.json']
Traceback (most recent call last):
  File "A.py", line 301, in <module>
    rm.run()
  File "A.py", line 200, in run
    rid_lonlat_dict, rid_num_dict = self.get_rid_lonlat()
  File "A.py", line 76, in get_rid_lonlat
    raise FileNotFoundError(file_path)
FileNotFoundError: xxx/rid_subid_trajs.json
# B.py
Normal: 0 => need_json_list:['rid_subid_trajs.json', 'rid_subid_trajsoverlap.json', 'spot_json.json']

可以看到A的报错,B并没抓取到,返回状态码还是0。。。所以请教各位一下。。。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧街凉风 2022-09-19 22:33:59

因为子进程引发异常 不会影响主进程

留蓝 2022-09-19 22:33:59

两个进程不可混为一谈。进程间的通信就是靠退出状态识别成功失败的。不同进程之间,没有异常这一说。
要判断状态 ,进程a要用相应的退出码和b 沟通。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文