[编辑] 我将整个问题的 SIGINT 改为 SIGTERM。
我有一个运行启动 jboss 的子进程脚本的脚本。
#!/bin/sh
....
start_jboss.sh &
trap 'kill -SIGTERM 0' EXIT HUP TERM INT
....
当我的脚本被杀死、终止或中断时,我想向 jboss 发送 SIGTERM 信号。但上述代码不会终止 JBoss。KILL
信号会杀死 JBoss(以下代码),但 JBoss 不会释放 H2 数据库锁。在我的例子中,释放 H2 锁很重要,因此我必须使用 SIGTERM 信号。
#!/bin/sh
....
start_jboss.sh &
trap 'kill -9 0' EXIT HUP TERM INT
....
我的 JBoss 使用端口 8080,因此以下命令给我一个 JBoss pid:
sudo netstat -lnpt | grep 8080
如果我执行以下命令:
kill -SIGTERM jboss_pid_from_netstat_command
然后 JBoss 中断并释放 H2 数据库锁。
如何修改我的陷阱操作以SIGTERM
向 JBoss 发送信号?我不知道为什么 SIGKILL 有效而 SIGTERM 无效。
[编辑] 我将整个问题的 SIGINT 改为 SIGTERM。
编辑
JBoss 启动脚本 ( ) 如果未设置,则standalone.sh
在前台进程中启动 JBoss ;如果设置了此变量,则在后台进程中启动 JBoss。因此,我在脚本中设置了此变量。然后,以下脚本可以正常工作:LAUNCH_JBOSS_IN_BACKGROUND
#!/bin/sh
....
export LAUNCH_JBOSS_IN_BACKGORUND=a
standalone.sh &
trap 'kill -SIGTERM 0' EXIT HUP TERM INT
....
#!/bin/sh
....
export LAUNCH_JBOSS_IN_BACKGORUND=a
standalone.sh &
trap 'kill -SIGTERM $(jobs -pr)' EXIT HUP TERM INT
....
#!/bin/sh
....
export LAUNCH_JBOSS_IN_BACKGORUND=a
standalone.sh &
jboss_script_id=$!
trap 'kill -SIGTERM $jboss_script_id' EXIT HUP TERM INT
....
我仍然不知道为什么以下代码不起作用。我在 Centos 上使用 bash 工作。我在 Ubuntu 上使用 dash 进行了测试,以下代码有效,但core dump
会引发警告。
(不行)
#!/bin/sh
....
standalone.sh &
trap 'kill -SIGTERM 0' EXIT HUP TERM INT
....
或(不起作用)
#!/bin/sh
....
standalone.sh &
trap 'kill -SIGTERM $(jobs -pr)' EXIT HUP TERM INT
....
或(不起作用)
#!/bin/sh
....
standalone.sh &
jboss_script_id=$!
trap 'kill -SIGTERM $jboss_script_id' EXIT HUP TERM INT
....
答案1
jboss 服务器可能有一个终止处理程序,以防在处理 I/O(例如写入数据库)期间被中断。可以处理TERM
和INT
信号,以确保当信号到达且进程忙于执行 I/O 时数据库不会损坏。
没有SIGKILL
任何宽限期 - 无论进程正在做什么,都会被无情地执行。SIGKILL 信号不允许任何处理程序。除非别无选择,否则这可能是避免使用 kill -9 终止进程的重要原因。
由于某种原因,终止整个进程组会干扰正确终止和删除数据库锁定。尝试像这样终止 jboss 服务器 - 注意,您可能需要扩展 kill 命令以确保脚本的所有子脚本也终止(我不知道您的整个脚本)。
trap 'kill -SIGTERM $(jobs -pr)' EXIT HUP TERM INT
这将杀死 jboss,因为该jobs
命令将返回从 shell 运行的后台进程(即您的情况下的 jboss 进程)。
答案2
我遇到过同样的问题。
如果您想终止正在运行的valgrind
进程,Ctrl+C将无法执行此操作。
由于valgrind
处理一些信号,我们可以向它发送信号以便它能够执行某些操作。如果您不知道信号列表,您可以通过以下方式检查(在终端上):
your_user_name:Directory$ kill -l
此命令将列出所有可用的信号。
使用 valgrind 运行你的程序(例如
valgrind --tool=memcheck ./prog
:)在左侧检查 valgrind PID。示例:==938== Memcheck,内存错误检测器
打开另一个终端窗口:
kill -SIGTRAP 938
这应该对你有用。
如果它对您不起作用,您可以尝试发送一些其他信号,我相信您会找到一个中断信号valgrind
但仍然会打印出报告。