简体   繁体   English

从python异常中杀死Bash脚本

[英]Kill Bash Script from within a python exception

I have a shell script calling Python inside it. 我有一个在其中调用Python的shell脚本。

#! /bin/bash

shopt -s extglob
echo "====test===="
~/.conda/envs/my_env/bin/python <<'EOF'

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"

If I execute this, the lines below still get printed. 如果我执行此操作,下面的行仍然会打印出来。

"end of script"

I want to exit the shell in the exception block of the python script and let the script not reach EOF 我想在python脚本的异常块中退出shell并让脚本不能到达EOF

Is there a way to create and kill a subprocess in the except block above, that will kill the entire shell script? 有没有办法在上面的except块中创建和subprocess ,这将终止整个shell脚本?

Can I spawn a dummy subprocess and kill it inside the exception block there by killing the entire shell script? 我可以通过杀死整个shell脚本来生成一个虚拟子进程并在异常块内杀死它吗?

Any examples would be helpful. 任何例子都会有所帮助。 Thanks in advance. 提前致谢。

The whole EOF ... EOF block gets executed within the Python runtime so exiting from it doesn't affect the bash script. 整个EOF ... EOF块在Python运行时内执行,因此退出它不会影响bash脚本。 You'll need to collect the exit status and check it after the Python execution if you want to stop the further bash script progress, ie: 如果要停止进一步的bash脚本进度,则需要收集退出状态并在Python执行后进行检查,即:

#!/bin/bash

~/.conda/envs/my_env/bin/python <<'EOF'
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"

From the shell script you have 2 options: 从shell脚本中您有2个选项:

  • set -e : all errors quit the script set -e :所有错误退出脚本
  • check python subcommand return code, abort if non-zero 检查python子命令返回代码,如果非零则中止

(maybe more details here: Aborting a shell script if any command returns a non-zero value? ) (这里可能有更多细节: 如果任何命令返回非零值,则中止shell脚本?

Now, if you don't want to change the handling from your shell script, you could get the parent process of the python script and kill it: 现在,如果您不想从shell脚本更改处理,则可以获取python脚本的父进程并将其终止:

except Exception as e:
    import os,signal,sys
    print("Exception: %s" % e)
    os.kill(os.getppid(),signal.SIGTERM)
    sys.exit(2)

if you need this on windows, this doesn't work ( os.kill doesn't exist), you have to adapt it to invoke taskkill : 如果你在Windows上需要这个,这不起作用( os.kill不存在),你必须调整它来调用taskkill

subprocess.call(["taskkill","/F","/PID",str(os.getppid())])

Now I would say that killing the parent process is bad practice. 现在我要说杀死父进程是不好的做法。 Unless you don't control the code of this parent process, you should try to handle the exit gracefully. 除非您不控制此父进程的代码,否则应该尝试优雅地处理退出。

One way to kill the entire script could be to save the PID and then using Python's system commands to execute a kill command on the PID when the exception happens. 杀死整个脚本的一种方法是保存PID,然后使用Python的系统命令在异常发生时对PID执行kill命令。 If we imported 'os' it would be something along the lines of: 如果我们导入'os',它将是:

# In a shell
PID=$$
...
// Some Python Exception happens
os.system('kill -9' + $PID)

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

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