Bash:最后(尝试,除外)异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3992243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:48:54  来源:igfitidea点击:

Bash: Finally (Try, Except) Exception

bashexecutionfinally

提问by Gabriel L. Oliveira

I want to execute some commands on the end of the bash script, even if the user press CTRL+C to cancel its execution.

我想在 bash 脚本的末尾执行一些命令,即使用户按 CTRL+C 取消其执行也是如此。

I know I can run the bash script from inside another programming language (for example, Python), so that I can use the 'finally' (try-finally) block to execute some code.

我知道我可以从另一种编程语言(例如 Python)中运行 bash 脚本,这样我就可以使用“finally”(try-finally)块来执行一些代码。

But knowing that StackOverflow is a center for exchanging fabulous ideas, I'm asking if is there a way to do what I want from inside my bash script.

但是知道 StackOverflow 是交流绝妙想法的中心,我想知道是否有办法从我的 bash 脚本中做我想做的事。

So, ideas?

那么,想法?

EDIT:

编辑:

What I want is kill every proccess opened within my bash, i.e., selenium and Xvfb proccesses.

我想要的是杀死在我的 bash 中打开的每个进程,即 selenium 和 Xvfb 进程。

I tried writing this to the code:

我尝试将其写入代码:

 trap "selenium_pids=$(ps ux | awk '/selenium/ && !/awk/ {print }');for pid in $selenium_pids; do kill -9 $pid;done; xvfb_pids=$(ps ux | awk '/Xvfb/ && !/awk/ {print }'); for pid in $xvfb_pids; do kill -9 $pid; done" EXIT

But this oblige me to press "CTRL+C" many times, on each run of subprocess from inside my script, something like:

但这迫使我多次按“CTRL + C”,在我的脚本中每次运行子进程时,例如:

Testing nsi.bd.helpcenter ...^C:  --  Total time: 0min 0seg
Testing nsi.bibliography ...^C:  --  Total time: 0min 0seg
Testing nsi.digitallibrary ...^C:  --  Total time: 0min 0seg
Testing nsi.digitallibraryinstaller ...^C:  --  Total time: 0min 1seg
Testing nsi.digitallibraryskins ...^C:  --  Total time: 0min 0seg
....#continues

Changing the final of the trap line from EXIT to SIGINT , like this:

将陷阱行的最后一行从 EXIT 更改为 SIGINT ,如下所示:

trap "selenium_pids=$(ps ux | awk '/selenium/ && !/awk/ {print }');for pid in $selenium_pids; do kill -9 $pid;done; xvfb_pids=$(ps ux | awk '/Xvfb/ && !/awk/ {print }'); for pid in $xvfb_pids; do kill -9 $pid; done" SIGINT

Makes the same thing.

做同样的事情。

What now to exit on the first CTRL+C?

现在退出第一个 CTRL+C 怎么办?

Because I tried to add a "exit 1" to the final of the string , like trap "... ;exit 1"

因为我试图在字符串的最后添加一个“exit 1”,比如 trap "... ;exit 1"

It worked to exit on the first CTRL+C, but didn't killed the processes I wanted.

它可以在第一个 CTRL+C 退出,但没有终止我想要的进程。

Ideas?

想法?

回答by Gabriel L. Oliveira

Got what I wanted with this code:

用这段代码得到了我想要的:

finalize_xvfb_and_selenium() {
    selenium_pids=$(ps ux | awk '/selenium/ && !/awk/ {print }')
    for pid in $selenium_pids; do 
        kill -9 $pid
    done 
    xvfb_pids=$(ps ux | awk '/Xvfb/ && !/awk/ {print }') 
    for pid in $xvfb_pids; do 
        kill -9 $pid
    done
}

finalize_xvfb_and_selenium_and_exit() {
    finalize_xvfb_and_selenium
    echo -e "\n\nXvfb and seleniumrc finalized. Exiting ..."
    exit 13
}

#trap (CTRL+C) signal, to finalize proccess running before exit
trap finalize_xvfb_and_selenium_and_exit SIGINT

I'm aware that there are better resources than using kill -9everywhere.

我知道有比kill -9随处使用更好的资源。

回答by dmckee --- ex-moderator kitten

You want to trap signals.

您想捕获信号。

When the user hits control-c at the terminal the OS issues a SIGINT to the current process. This signal can be trapped and handles. How you do that is a shell dependent issue and you should check your shells man page.

当用户在终端点击 control-c 时,操作系统会向当前进程发出 SIGINT。这个信号可以被捕获和处理。你如何做到这一点是一个依赖于 shell 的问题,你应该检查你的 shell 手册页。

Note that some signals can not be trapped. Notably SIGKILL which is what kill -9sends.

请注意,某些信号不能被捕获。值得注意的是 SIGKILLkill -9发送的内容。



In light of the edit: bash can return the process ID of programs that you start. It would be possible to capture all them as you go so that you don't have to parse the output of ps. You might also consider sending you children some other signal (maybe SIGUSR1) having already set up a trap on that so that they will recursively kill theirchildren.

根据编辑:bash 可以返回您启动的程序的进程 ID。可以随时捕获所有它们,这样您就不必解析ps. 您还可以考虑向您的孩子发送一些其他信号(可能是 SIGUSR1),因为他们已经设置了一个陷阱,以便他们递归地杀死他们的孩子。

All that said, your getting into deep shell magic territory. There are some books around which might help, but I don't know the titles off the top of my head.

综上所述,您进入了深壳魔法领域。有一些书可能会有所帮助,但我不知道头顶上的书名。