[英]Handling specific Python error within Bash call?
我正在使用line_profiler
,它允许您在Python代码库中的任何位置放置@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 defined
在stderr
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解决方案,它将stdout
和stderr
保留为单独的流(带有警告, stderr
在stdout
之后出现),并且仅检查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 ...
。
>&2
将stdout
重定向到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.