假设您有一个由用户
foo
和组 foo
拥有的守护进程,并且可以通过 sudo systemctl start foo.service
启动。
该守护进程大部分时间都在等待子进程睡眠,但可以被
SIGUS1
中断以通过陷阱执行某些任务。
收到信号后,它将从命名管道读取数据,执行一些任务并将 stdout 和 stderr 返回到另一个命名管道。
假设有一个用户
bar
,属于 foo
组。
此用户有权访问名为
talk_foo
的 shell 脚本,该脚本尝试发送信号,然后从守护程序的输出命名管道中读取以回显给用户。
用户
bar
可以发送kill -SIGUSR1 <DAEMON PID>
吗?到目前为止我还没有成功(除非使用sudo
),因为该操作是不允许的。我想这是因为 use bar
不拥有守护进程,也不属于同一进程组。
在此设置中是否有办法与
foo
守护进程进行通信,或者我应该重新考虑事情?
感谢所有评论信息的人,这非常有帮助。
我最终放弃了使用睡眠周期并用
kill -SIGUSR1
信号中断的实现,其背后的动机是将 CPU 使用率保持在 while true
循环内较低。
感谢 @F.Hauri-GiveUpGitHub 和 @Barmar,从命名管道读取数据以阻止进程,直到用户写入该管道可以解决 CPU 使用问题以及通信问题。
以下是我的最终结果,主要供以后参考。干杯!
在守护进程示例中
FIFO=my_pipe
# allow group access to write to input
mkfifo 0620 $FIFO.in
# allow group access to read from output
mkfifo 0640 $FIFO.out
some_custom_cmd() {
#do whatever here
echo "Responding... " $@
}
read_and_respond() {
exec <3$FIFO.in # open input pipe
# attempt to read from it
# blocking process here until user writes to
# $FIFO.in
read -u 3 -r user_cmd
# once process continues and we capture user input
# close input and open ouptut pipe
exec 3<&- 4>$FIFO.out
# perform some task, writing to pipe
# which blocks process until user reads from
# $FIFO.out
some_custom_cmd $user_cmd >&4 2>&4
# close fd 4 when done
exec 4>&-
}
while true
do
# blocking process
read_and_respond
done
上述守护进程将在后台运行。
在用户脚本方面...
#! /usr/bin/env bash
# assuming everything is in the same
# directory... probably best to put in
# some /run/<group>/ directory
FIFO=my_pipe
talk_to_daemon() {
#open file descriptor
exec 3>$FIFO.in
echo $@ >&3 # send arguments to daemon, releases blocking
exec 3>&- 4<$FIFO.out #close fd 3, open fd 4 for reading
#blocks process until daemon responds by writing to
# $FIFO.out
# here we are just verbatim printing to the user
cat <&4
exec 4<&- # closes fd 4 when done
}
talk_to_daemon $@
@gabor.zed 提到配置 sudoers。这将允许使用陷阱的原始设置,但我认为上述方法更干净。