问题标签 [bash-trap]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
56808 浏览

bash - 如何在 Bash 脚本中捕获退出代码

我的 bash 代码中有很多退出点。我需要在退出时做一些清理工作,所以我使用陷阱为退出添加回调,如下所示:

问题是退出代码不同,我需要做相应的清理工作。我可以在 mycleanup 中获得退出代码吗?

0 投票
2 回答
9025 浏览

bash - 无法在后台 shell 中捕获 SIGINT 信号

在子/后台进程中运行时,我无法捕获信号。

这是我的简单 bash 脚本:

当运行这个和以后做

一切都按预期工作,它打印trapped并退出。

现在,如果我从这样的父脚本启动相同的脚本:

然后孩子不再捕获信号......?

更改为使用 SIGTERM 而不是 SIGINT 后,它似乎工作正常......?

0 投票
2 回答
1995 浏览

bash - 从陷阱处理程序获取 bash 中的函数回溯(使用调用者)

我知道您可以使用“调用者”来回溯 b​​ash 中的函数调用:

印刷:

我的问题是,假设我有一个脚本,它使用“set -e”来终止任何未经检查的失败。是否可以获得脚本失败的行号(及其调用者)

我尝试过天真地做:trap 'Backtrace' EXIT,但这给了我 '1 main ./test.sh' 而不是失败命令的行号

0 投票
2 回答
4903 浏览

bash - 如何在 bash 脚本中正确捕获 SIGQUIT?

我可以编写可以很好地捕获的 shell 脚本SIGINT,但我似乎无法捕获SIGQUIT.

执行此脚本并按下CTRL-C具有预期的效果,但按下CTRL-\(据我所知,应该触发)除了在终端中SIGQUIT打印之外什么都不做。^\为什么?

我有两个运行理论。首先是 和 的语义SIGINT不同SIGQUIT,因此SIGQUIT只发送到子进程sleep,而同时SIGINT发送到子进程和父 bash 进程。如果是这种情况,它记录在哪里?

我的第二个理论是 bash 不仅SIGQUIT默认忽略(即,有一个无操作处理程序)(如手册页所建议的那样),而且根本不允许它被捕获。这个理论与第一个理论重叠,因为它可能是SIGQUIT同时发生在父母和孩子身上的情况,但父母 ( bash) 就是无法捕获它。如果是这种情况,是否有任何方法可以捕获SIGQUITbash 脚本?...也许shopt我可以设置一些?

编辑:这是在运行 bash 4.1.5 的 gnome-terminal 2.32.0 中的 Ubuntu 10.10 上,并且是^\配置为发出 SIGQUIT(由向其他程序发出 SIGQUIT 报告stty -a并确认)。^\ping

更新:我刚刚发现问题一定是由于 gnome-terminal 造成的。如果我从虚拟控制台运行这个脚本(即ctrl-alt-f1退出 X),当我按下 SIGQUIT 时,它会很好地捕获 SIGQUIT ^\。相同的 bash 和所有内容,因此唯一的区别必须是终端仿真器。所以现在我的问题变成了:如何配置 gnome-terminal 在这方面表现得像虚拟控制台?我在虚拟控制台和 gnome-terminal 中diff的输出stty -a,虽然存在差异,但似乎没有什么直接相关的(例如,它们都有quit = ^\;)。

更新2:另一个实验。只需$ sleep 60在 gnome-terminal 中执行;按下^\,信号未被捕获。现在$ sleep 60在虚拟控制台中执行;按下^\并捕获信号 - 进程打印Quit退出。但现在$ ping google.com在 gnome-terminal 中运行并按^\-- 信号被捕获并按预期处理。所以 gnome-terminal 有一些奇怪的地方,例如 SIGQUIT 可以被某些程序捕获,但不能被其他程序捕获,即使其他程序在从虚拟控制台调用时确实捕获了它。也许我应该升级我的 gnome 终端。

0 投票
1 回答
7992 浏览

bash - bash 使用陷阱 SIGCHLD 重新启动子进程?

我已经看到监视程序在脚本中使用“ps”或“服务状态(在 Linux 上)”定期检查进程状态,或者在 C/C++ 中分叉并等待进程......

我想知道是否可以使用带有陷阱的bash并在收到SIGCLD时重新启动子进程?

我已经按照以下想法在 RedHat Linux 上测试了一个基本套件(当然它没有工作......)

正在启动的 bash 脚本只是休眠几秒钟然后退出。

观察到几个问题:

  • 当 shell 在前台启动时,SIGCHLD 将只处理一次。陷阱复位信号处理是否像信号()?
  • 脚本及其子进程似乎对 SIGINT 免疫,这意味着它们不能被 ^C 阻止
  • 由于无法关闭,我关闭了终端。剧本似乎是HUP,留下了许多僵尸孩子。
  • 在后台运行时,脚本导致终端死机

...无论如何,这根本不起作用。我不得不说我对这个话题知之甚少。有人可以建议或给出一些工作示例吗?有这种用途的脚本吗?

那么在 bash 中使用 wait 怎么样?

谢谢

0 投票
1 回答
4386 浏览

bash - Perl 在 bash 中捕获 Ctrl-C (sigint)

我正在阅读How do we capture CTRL ^ C - Perl Monks,但我似乎无法获得正确的信息来帮助解决我的问题。

问题是 - 我有一个无限循环,并且“多行”打印输出到终端(我知道我会被告知要ncurses改用 -​​ 但对于短脚本,我更愿意写一堆printfs)。我想以这样的方式捕获 Ctrl-C,即脚本仅此多行打印输出完成后才会终止。

脚本是(Ubuntu Linux 11.04):

现在,如果我运行它,然后按 Ctrl-C,我会得到类似这样的东西(注意,_脚本终止后终端光标的指示位置):

或者:

...但是,我想得到:

显然,处理程序正在运行——但并不完全按照我期望的时间(或顺序)运行。有人可以澄清我该如何解决这个问题,所以我得到我想要的输出?

非常感谢您的任何答案,干杯!

0 投票
3 回答
4915 浏览

bash - eval 中的 Bash、CTRL+C 不会中断主脚本

在我的 bash 脚本中,我正在运行一个存储在$cmd变量中的外部命令。(可以是任何东西,甚至是一些简单的 bash oneliner。)

如果在运行脚本时按下ctrl+ C,我希望它终止当前正在运行的脚本,$cmd但它仍应继续运行主脚本。但是,我想保留在主脚本运行时使用ctrl+终止主脚本的选项C

知道如何用一些不错的 bash 方式来做吗?

根据答案应用的更改:

现在,在“Ooook1?”时按ctrl+ C只有在读取完成后,read 才会中断 eval。(它会在“Oook2”之前中断)但是它会立即中断“sleep 4”。

在这两种情况下,它都会做正确的事情——它只会中断 eval 子shell,所以我们快到了——只是那种奇怪的读取行为..

0 投票
1 回答
5408 浏览

bash - Bash 信号捕获未检测到在声明“陷阱”块后更改的变量

我有一堆通用的清理代码,每当某个 bash 脚本退出时,无论它是正常退出还是被中断,都需要执行这些代码。我想我会使用trap "..." EXIT伪信号来实现这一点。

除了一般的清理工作之外,还有一项特定的清理工作只有在脚本正常完成时才应该进行。我想我可以通过让“陷阱”块测试一个变量来触发它,如下所示:

但是,这不起作用。运行以下代码将永远不会回显“测试”。在之后添加显式exit调用done=true;不会改变任何内容。我错过了什么?

干杯!

0 投票
3 回答
12507 浏览

bash - 通过传递参数来捕获函数?

我一直在到处搜索,我开始相信除了拥有全局变量之外别无他法,但我相信 stackoverflow.com 中的大师可能会帮助我:

bash 中是否有任何方法可以通过向函数传递参数来捕获函数?
例如,trap <function_name> <arg_1> <arg_2> SIGINT

0 投票
1 回答
6346 浏览

bash - 使用 bash 中的陷阱捕获已终止后台进程的 pid

我正在编写一个生成许多后台进程的 bash 脚本。我希望在进程终止时收到通知;我想知道终止进程的pid。

我看过 using wait,这样每个生成的进程的 pid 都被捕获并存储在一个数组中,然后迭代数组,并在每个进程上调用 wait 。此处以各种方式描述了此技术:

https://stackoverflow.com/a/356154/366856

如果我理解正确的话,这个问题是,如果您想在单个进程终止后立即执行某些操作,则效率可能相对较低。例如,如果您生成进程 A 和 B,并且 B 在 A 之前完成,则执行必须等待 A 和 B 都完成。我需要在 B 完成后立即执行操作。

这似乎trap SIGCHLD是在孩子终止时立即执行操作的方式,但问题是我找不到确定 SIGCHLD 信号源的 pid 的方法,这也是我需要的。我发现的最接近此工作示例的是本文中的第三个代码示例:

http://www.linuxforums.org/forum/programming-scripting/103996-multithreading-bash.html#post510187

为方便起见,我在这里复制粘贴:

我觉得这个例子行不通,因为作者犯了trap多次调用的错误,每次在trap's 参数中捕获不同的 pid 变量。每次调用 trap 时,它都会覆盖上一次调用,因此将捕获任意 pid。我一直找不到更好的技术。

有没有办法使用 bash 中的陷阱获取终止的子进程的 pid?

更新

我只是想指出这个资源,它包含迄今为止我所看到的解决这个问题的最佳、最全面的概述:

http://mywiki.wooledge.org/ProcessManagement#I_want_to_process_a_bunch_of_files_in_parallel.2C_and_when_one_finishes.2C_I_want_to_start_the_next._And_I_want_to_make_sure_there_are_exactly_5_jobs_running_at_a_time