관리자 권한이 있는 다른 사용자가 해당 스크립트를 사용하려고 하는 동안 최대 절전 모드로 전환되는 스크립트를 실행하고 있다고 가정해 보겠습니다 pkill
. 가능하다면 해당 신호를 내 프로세스에 보낸 사용자를 어떻게 캡처할 수 있습니까?
kill -9 <my_script>
SIGKILL로는 아무 것도 캡처하거나 수행할 수 없기 때문에 이와 같은 기능으로는 아무것도 캡처할 수 없다는 것을 알고 있습니다 .
답변1
예, 가능합니다. 비록 스크립트에서는 아닐 수도 있습니다. 이렇게 하려면 다음을 사용하여 신호 처리기를 설정해야 합니다.sigaction
플래그를 사용 SA_SIGINFO
하고 동일한 서명된 핸들러를 제공합니다.
void handler(int sig, siginfo_t *info, void *ucontext)
신호를 처리하기 위해 호출될 때 두 번째 인수로 받는 포인터에는 siginfo_t
송신 프로세스의 프로세스 식별자( ) 및 송신 프로세스의 읽기 사용자 식별자( )와 같은 정보가 포함됩니다. 전송된 신호를 사용하기 위해 채워집니다.info->si_pid
info->si_uid
kill
또는sigqueue
.
이것을 Python으로 구현하려면 많은 작업이 필요합니다.신호 모듈구조에 액세스하는 방법은 제공되지 않습니다 siginfo_t
.
답변2
배쉬 + ctypes.sh
재미로 @StephenKitt의 솔루션을 사용하여 다음은 bash의 예입니다.배쉬 플러그인 ctypes.sh(이 예에서는 컴파일하고 설치해야 합니다 /usr/local
.)
불행하게도 두 구성 모두 너무 복잡 sigaction
하여 내장 명령이 작동할 수 없습니다. 따라서 이러한 구조는 수동으로 정의해야 합니다. 이는 매우 성가신 일이며 이식성이 없습니다(운영 체제나 아키텍처에). 이 예 에서는 x86_64 아키텍처에서 Linux >= 4.6(때문에)을 가정합니다.siginfo_t
ctypes.sh
struct
info->si_pkey
#!/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