程序my_prog
将在启动后启动。它创建了/tmp/my_prog.sock
拥有的Unix域套接字root:root
。
我正在努力做到以下几点:
www-data:www-data
。这是我的单元文件my_prog.service
的第一个版本:
[Unit]
Description=My Program
After=network.target
[Service]
ExecStart=/usr/local/bin/my_prog
ExecStartPost=chmod www-data:www-data /tmp/my_prog.sock
ExecStopPost=rm -f /tmp/my_prog.sock
[Install]
WantedBy=multi-user.target
这个版本有两个问题:
永远不会更改/tmp/my_prog.sock
的所有者 - 始终root:root
。
/tmp/my_prog.sock
永远不会被删除。
我想命令chmod
和rm
过早执行会给我带来意想不到的结果:
chmod
在my_prog
完成创建套接字文件之前运行,rm
在my_program
退出之前运行(my_program
禁止其套接字文件在运行时被删除?)。以下是我的第二个版本,它未能给我正确的结果:
档案my_prog.service
:
[Unit]
Description=My Program
After=network.target
[Service]
ExecStart=/usr/local/bin/my_prog
[Install]
WantedBy=multi-user.target
档案my_prog-socket.path
:
[Unit]
Description=My program - notify socket existence
[Path]
PathExists=/tmp/my_prog.sock
档案my_prog-socket.service
:
[Unit]
Description=My program - change owner and remove socket
[Service]
ExecStart=chown www-data:www-data /tmp/my_prog.sock
ExecStopPost=rm -f /tmp/my_prog.sock
我已经完成了所有技巧。 我的单位文件出了什么问题? 是否有比上面更优雅的设计?
谢谢!
P.S。:对于那些感兴趣的人,这个旧版本/etc/init.d/my-prog
至少按预期工作:
#!/bin/sh
### BEGIN INIT INFO
# Provides: my-program
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My Program
# Description: My Program
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/bin/my_prog
NAME=my-program
DESC="My Program"
SCRIPTNAME=/etc/init.d/$NAME
PIDFILE=/var/run/my-prog.pid
SOCKET_FILE="/tmp/my-prog.sock"
test -x $DAEMON || exit 0
grant_socket_access()
{
#Wait program to create socket.
count=1
while [ "$count" -lt "50" ]
do
if [ -S $SOCKET_FILE ]
then
chown www-data:www-data $SOCKET_FILE
return 0
fi
sleep 0.2
count=`expr $count + 1`
done
echo >&2 "$NAME fails to grant access to Unix socket file: $SOCKET_FILE"
return 1
}
. /lib/lsb/init-functions
case "$1" in
start)
log_daemon_msg "Starting $DESC" $NAME
rm -f $SOCKET_FILE
if start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -b -m
then
grant_socket_access
else
rm -f $SOCKET_FILE
fi
log_end_msg $?
;;
stop)
log_daemon_msg "Stopping $DESC" $NAME
rm -f $SOCKET_FILE
if start-stop-daemon --stop --retry TERM/10/KILL/5 --quiet --pidfile $PIDFILE --exec $DAEMON --remove-pidfile
then
log_daemon_msg "$DESC" "$NAME stopped"
log_end_msg 0
else
log_end_msg 1
fi
;;
reload|force-reload)
log_daemon_msg "Reloading $DESC" $NAME
rm -f $SOCKET_FILE
if start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE --exec $DAEMON
then
grant_socket_access
log_end_msg $?
else
log_end_msg 1
fi
;;
restart)
log_daemon_msg "Restarting $DESC" $NAME
$0 stop
$0 start
;;
status)
status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $?
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload|status}" >&2
exit 1
;;
esac
exit 0
修改
根据@Mark Stosberg友情提供的食谱,我已经修改了原来的第一个版本,刚才有/bin/chown
和/bin/rm
。
我从新版本中的第ExecStopPost=/bin/rm -f /tmp/my_prog.sock
行获得了所需的结果。但是,ExecStart=/bin/chown www-data:www-data /tmp/my_prog.sock
会输出此错误:
chown[8388]: /bin/chown: connot access '/tmp/my_prog.socket'
答案 0 :(得分:1)
通过systemd-analyze verify ./your-file.service
运行脚本会发现问题:
[/home/mark/tmp/t.service:7] Executable path is not absolute, ignoring: chmod www-data:www-data /tmp/my_prog.sock
[/home/mark/tmp/t.service:8] Executable path is not absolute, ignoring: rm -f /tmp/my_prog.sock
man systemd.service
中的文档记录了可执行路径必须是绝对路径的要求。
您的错误是指扩展名为.socket
的文件,但您的示例显示的是.sock
扩展名。确认您在所有地方始终使用.sock
或.socket
。
如果您的服务不需要以root用户身份运行,则可以通过使用chown
和User=
指令来提高安全性并避免Group=
的需要作为不同用户的服务。这将创建一个由该用户而不是root用户拥有的套接字。
答案 1 :(得分:0)
谢谢!绝对可执行路径解决了我的第二个问题。我的第一个问题仍然存在
您的第一个问题是chmod不使用“ owner:group”,您真的想要“ chown”
例如:
ExecStartPost = 小丑 www-data:www-data /tmp/my_prog.sock