捕获哪个用户发送终止信号

捕获哪个用户发送终止信号

假设我正在运行一些只是休眠的脚本,而另一个具有管理员权限的用户尝试使用pkill.如果可能的话,我如何捕获哪个用户将该信号发送到我的进程?

我知道类似的东西kill -9 <my_script>不允许我捕获任何东西,因为我们无法捕获或使用 SIGKILL 做任何事情。

答案1

是的,这是可能的,尽管可能不是来自脚本。为此,您需要使用以下命令设置信号处理程序sigactionSA_SIGINFO标志,并提供一个签名相同的处理程序

void handler(int sig, siginfo_t *info, void *ucontext)

当调用它来处理信号时,它作为第二个参数接收的指针将包含发送进程的进程标识符 ( ) 和发送进程的读取用户标识符 ( )siginfo_t等信息。这些是为使用发送的信号而填写的info->si_pidinfo->si_uidkill或者sigqueue

在 Python 中实现这一点需要大量的工作,因为信号模块不提供访问结构的方法siginfo_t

答案2

bash + ctypes.sh

只是为了好玩,使用 @StephenKitt 的解决方案,这是 bash 中的一个示例,使用bash插件 ctypes.sh(对于本示例,必须对其进行编译和安装/usr/local)。

遗憾的是,这两种结构sigactionsiginfo_t过于复杂,无法让ctypes.sh的内置struct命令发挥作用。因此必须手动定义这些结构。这是一件非常烦人的苦差事,而且它是不可移植的(无论是对于操作系统还是对于体系结构)。此示例假设info->si_pkeyx86_64 架构上的Linux >= 4.6(因为)。

#!/bin/bash

. /usr/local/bin/ctypes.sh || exit 2

handler () {
    local -a info=(int int int int uint32 uint32 int int64 int64 int64 int pointer int int pointer long int short pointer pointer int pointer int unsigned)
    unpack $3 info

    echo ''
    echo "handler($2, info={${info[@]}}, $4);"
    echo -- handling signal $2 --
    echo "info->si_pid=${info[4]}"
    echo "info->si_uid=${info[5]}"
    return
}
callback -n handler handler void int pointer pointer

SIGUSR2=12
SA_SIGINFO=4

act=(
    $handler
    long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0
    int:$SA_SIGINFO
    pointer:0
)
sizeof_act=$(( 8 + 16 * 8 + 4 + 8 ))

dlcall -n pact -r pointer malloc $sizeof_act
[ $pact != pointer:0 ] || exit 1
pack $pact act

dlcall -n ret -r int sigaction int:$SIGUSR2 $pact pointer:0
[ $ret = int:0 ] || exit 1

echo "sigaction(SIGUSR2, act={${act[@]}}, NULL) = $ret"

echo ''
echo run this: kill -$SIGUSR2 $$
sleep 99

执行:

术语1:

$ ./siginfo.bash 
sigaction(SIGUSR2, act={pointer:0x7ff26f0d3010 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 int:4 pointer:0}, NULL) = int:0

run this: kill -12 24250

术语2:

$ echo $$
21864
$ id -u
1000
$ kill -12 24250
$ 

第 1 项的结果:

handler(int:12, info={int:12 int:0 int:0 int:0 uint32:21864 uint32:1000 int:0 int64:0 int64:0 int64:0 int:0 pointer:0 int:0 int:0 pointer:0 long:0 int:0 short:0 pointer:0 pointer:0 int:0 pointer:0 int:0 unsigned:0}, pointer:0x7fff4583a500);
-- handling signal int:12 --
info->si_pid=uint32:21864
info->si_uid=uint32:1000

相关内容