我在 Linux 中有一个名为appSevice
当我使用这些命令启动和停止时的服务,它可以工作:
sudo systemctl start appSevice.service;
sudo systemctl stop appSevice.service;
但是当我尝试从 JAVA 代码执行这些时,例如:
Runtime.getRuntime().exec(new String[]{"systemctl", "stop", "appService.service"});
...它不起作用,我收到此错误:
> Failed to stop appService.service: Interactive authentication required
这是我的服务:
[Service]
Type=simple
ExecStart=/opt/soft/v1/launchAppService.ksh start
User=Jms-User
Restart=on-abort
有没有办法避免此错误并在不提供密码的情况下运行服务?
答案1
有以下三种方法:
- 放入
appService.service
并~/.config/systemd/system/
取出User=
线。然后你可以通过以下方式控制它:
systemctl --user start appService.service
systemctl --user stop appService.service
- 添加 polkit 规则。我认为这个问题非常接近您要寻找的内容:systemd 以组中的非特权用户身份启动。如果您使用的是 debian/ubuntu (polkit < 106),那么这将起作用:
/etc/polkit-1/localauthority/50-local.d/service-auth.pkla
---
[Allow yourname to start/stop/restart services]
Identity=unix-user:youname
Action=org.freedesktop.systemd1.manage-units
ResultActive=yes
如果您使用的是 Arch/Redhat (polkit >= 106),那么这将有效:
/etc/polkit-1/rules.d/service-auth.rules
---
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
subject.user == "yourname") {
return polkit.Result.YES;
} });
sudo
。我不太喜欢这个,因为sudo
不需要依赖NOPASSWD:
配置,而且我不认为它被设计为间接调用。这就是 polkit 的设计目的。
/etc/sudoers.d/sysctl
---
youname ALL = NOPASSWD: /bin/systemctl
如果这是您计划分发的软件,我肯定会使用 polkit 解决方案并按组进行(根据链接的答案)。这意味着您不必对用户名进行硬编码,而是将您喜欢的用户添加到该组中以获得该功能。
答案2
也许您应该从用户创建一个单元?
systemctl edit --user --force --full myNewUnit
将在编辑器中打开一个新文件~/.config/systemd/user/myNewUnit.service
插入内容,保存并使用它而无需 root 权限
systemctl enable --user myNewUnit
systemctl start --user myNewUnit
systemctl status --user myNewUnit
或者,如果您需要编辑而不是不打开--force
systemctl edit --user --full myNewUnit
我希望我没有弄乱任何东西并且它会有用