繁体   English   中英

在Bash调用中处理特定的Python错误?

[英]Handling specific Python error within Bash call?

我正在使用line_profiler ,它允许您在Py​​thon代码库中的任何位置放置@profile装饰器,并返回行输出。

但是,如果您尝试执行包含一个此类@profile装饰器的python代码而不加载该line_profiler模块,则该代码将失败,并出现NameError,因为此类装饰器是由此外部库定义和注入的。

我想要一个bash命令,尝试使用香草python运行我的python脚本。 然后,当且仅当错误包含NameError ,我才想再次尝试一下。 到目前为止,这是我得到的:

python -u $file || python -m kernprof -l -v --outfile=/dev/null $file"

问题当然是,如果我的python代码根本没有任何错误,无论是ValueError还是IndentationError或其他任何错误,它都会尝试探查器。 如果错误包含字符串NameError: name 'profile' is not defined我只想运行探查器NameError: name 'profile' is not definedstderr NameError: name 'profile' is not defined找到NameError: name 'profile' is not defined

没有line_profiles时,猴子补丁配置文件会更好吗?

就像是

try:
    import line_profiles
except:
    import warnings
    warnings.warn("Profile disabled")

    def profile(fn):
        def wrapper(*args, **kw):
            return fn(*args, **kw)
        return wrapper

这样,无论哪种情况,您的代码都可以运行而不会使事情复杂化。

这是一个可用的Bash解决方案,它将stdoutstderr保留为单独的流(带有警告, stderrstdout之后出现),并且仅检查stderr是否显示错误消息(尽管这可能是过大的)。

它很简单,只需将stderr输出保存到文件即可。 它还处理包含空格的脚本名称(通过在需要的地方适当地引用变量扩展名)和/或以-开头(通过在文件名前传递--以关闭标志处理),因为它是我的OCD petpeeve。

成功执行后,或者如果出现的错误不是预期的错误,则显示第一个python命令的stderr 否则(针对预期的错误)将被隐藏。

用法是$ ./check <script>

#!/bin/bash

if [[ $# -ne 1 ]]; then
    echo "Expected one argument: the script" >&2
    exit 1
fi

script=$1

if [[ ! -e $script ]]; then
    echo "'$script' does not exist or is not a regular file" >&2
    exit 1
fi

if ! python -- "$script" 2>saved_stderr &&
   grep -q "NameError: name 'profile' is not defined" saved_stderr; then

    # Try again with the kernprof module.
    python -m kernprof -l -v --outfile=/dev/null -- "$script"

else
    # Either success or an unexpected error. Show stderr.
    cat saved_stderr >&2
fi

rm saved_stderr
  • 要检查命令的返回状态是否为零(即成功),只需执行

     if <cmd>; then <if successful>; fi` 

    ! 否定退出状态,所以if ! <cmd> ... if ! <cmd> ...可用于检查故障。 ! 仅适用于上述python命令,不适用于python ... && grep ...

  • >&2stdout重定向到stderr (它与1>&2相同,但是保存了一个字符,这有点愚蠢,但是出于说明目的,我将其包括在内是因为这是一个常见的习惯用法。)

创建一个简单的Python包装器似乎要简单得多,因为在Python中,您可以访问出现问题的地方。

假设您的$file使用通用的__name__ == '__main__'惯用法,如下所示:

if __name__ == '__main__':
    main()

你可以创建一个包装像

import yourfile
try:
    file.main()
except NameError:
    import kernprof
    # hack hack, quickly constructed from looking at main() in kernprof.py
    prof = kernprof.ContextualProfile()
    execfile_ = execfile
    ns = locals()
    try:
        prof.runctx('execfile_(%r, globals())' % (yourfile,), ns, ns)
    finally:
        prof.print_stats()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM