我有一个在其中调用Python的shell脚本。
#! /bin/bash
shopt -s extglob
echo"====test===="
~/.conda/envs/my_env/bin/python <
import sys
import os
try:
print("inside python")
x = 2/0
except Exception as e:
print("Exception: %s" % e)
sys.exit(2)
print("at the end of python")
EOF
echo"end of script"
如果我执行此操作,下面的行仍然会打印出来。
"end of script"
我想在python脚本的异常块中退出shell并让脚本不能到达EOF
有没有办法在上面的except块中创建和终止subprocess,这会杀死整个shell脚本?
我可以通过杀死整个shell脚本来生成一个虚拟子进程并在异常块内杀死它吗?
任何例子都会有所帮助。
提前致谢。
只需保存你调用python的行的返回值,并在EOF之后检查它
或者具有非零返回码状态退出shell(set -e)。 也不要做sys.exit(-1)。 退出代码是正面的。 便携式方面0-255
@ Jean-FranoisFabre我不想set -e因为我希望一些错误无声地失败并继续在脚本中运行,但特别是这个python异常会杀死整个脚本。 谢谢,不会使用-1,编辑帖子。
这个问题不重复......
@ritlew为什么不重复? 它基本上归结为你评论的内容(查看链接)。
问题是如何根据python脚本的作用退出脚本,正如提问者所重申的那样。
它出现了,被问到的人接受了答案......这是前一个重复链接中的一个副本。 你对提问者想要的内容的解释很有趣,但不是真实的。
它出现了......反过来说:)
整个EOF ... EOF块在Python运行时内执行,因此退出它不会影响bash脚本。如果你想停止进一步的bash脚本进程,你需要收集退出状态并在Python执行后检查它,即:
#!/bin/bash
~/.conda/envs/my_env/bin/python <
import sys
sys.exit(0x01) # use any exit code from 0-0xFF range, comment out for a clean exit
print("End of the Python script that will not execute without commenting out the above.")
EOF
exit_status=$? # store the exit status for later use
# now lets check the exit status and see if python returned a non-zero exit status
if [ $exit_status -ne 0 ]; then
echo"Python exited with a non-zero exit status, abort!"
exit $exit_status # exit the bash script with the same status
fi
# continue as usual...
echo"All is good, end of script"
这样就可以了。 万分感谢!:)
从shell脚本中您有2个选项:
set -e:所有错误退出脚本
检查python子命令返回代码,如果非零则中止
(这里可能有更多细节:如果任何命令返回非零值,则中止shell脚本?)
现在,如果您不想从shell脚本更改处理,则可以获取python脚本的父进程并将其终止:
except Exception as e:
import os,signal,sys
print("Exception: %s" % e)
os.kill(os.getppid(),signal.SIGTERM)
sys.exit(2)
如果你在Windows上需要这个,这不起作用(os.kill不存在),你必须调整它来调用taskkill:
subprocess.call(["taskkill","/F","/PID",str(os.getppid())])
现在我要说杀死父进程是不好的做法。除非您不控制此父进程的代码,否则应该尝试优雅地处理退出。
谢谢! 不os.kill取2个参数,另一个是sig吗?
是的,它确实!编辑。
谢谢,这就是我想要的。 更清洁,更好。 奇迹般有效。
我不会称之为更干净,但如果你有300个shell脚本,你可能不想全部修改它们,所以这是仅在python脚本中进行更改的解决方案。 这只有在shell BTW直接调用时才有效。
杀死整个脚本的一种方法是保存PID,然后使用Python的系统命令在异常发生时对PID执行kill命令。如果我们导入'os',它将是:
# In a shell
PID=$$
...
// Some Python Exception happens
os.system('kill -9' + $PID)