我有一个围棋二进制文件,它使用 cmd := exec.Command("xdpyinfo")
然后叫 cmd.Output()
.程序在终端机上如期运行。然而,当我以systemd服务的形式运行这个程序时,没有任何输出。cmd.Output()
.我的程序作为服务运行,但调用cmd.Output()却返回一个错误。
我试着让这个问题尽可能的容易重现。
我有一个可执行的go二进制文件,名为test,地址是: /home/myusername/Projects/test
二进制是用 go build
从单一 main.go
文件,其中包含以下代码。
package main
import (
"fmt"
"log"
"log/syslog"
"os/exec"
)
func main() {
logwriter, e := syslog.New(syslog.LOG_NOTICE, "testprog")
if e == nil {
log.SetOutput(logwriter)
}
cmd := exec.Command("xdpyinfo")
out, err := cmd.Output()
if err != nil {
log.Print(fmt.Errorf("ERROR: %v", err))
}
log.Print(string(out))
}
日志记录只是为了测试的目的 因为真正的代码是一个更大的应用程序的一部分。
当我在终端上运行测试二进制文件时,我看到了预期的输出,来自于 xdpyinfo
然而,当尝试在服务中运行相同的二进制文件时,它的输出是--------。ERROR: exit status 1
.
我运行服务的步骤。
/etc/systemd/system/TestProg.service
:[Unit]
Description=Test service
ConditionPathExists=/home/myusername/Projects/test/test
After=network.target
[Service]
Type=simple
Restart=on-failure
RestartSec=10
startLimitIntervalSec=60
WorkingDirectory=/home/myusername/Projects/test
ExecStart=/home/myusername/Projects/test/test
[Install]
WantedBy=multi-user.target
sudo systemctl enable TestProg.service
sudo systemctl start TestProg.service
我也试过在以下位置找到单元服务文件: /lib/systemd/system/TestProg.service
并添加 User=username
在...之下 Type=simple
.
我已经尝试了几种不同的配置来尝试让它工作。我也试过用 SysProcAttr
(有实际的uid和gid)。
cmd := exec.Command("xdpyinfo")
cmd.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{
Uid: uint32(uid),
Gid: uint32(gid),
NoSetGroups: true,
},
}
out, err := cmd.Output()
if err != nil {
log.Print(fmt.Errorf("ERROR: %v", err))
}
我现在开始觉得我错过了一些更基本的东西。
你必须在你的用户会话中运行它(也就是启动你的X11会话)。
systemd-run --user -t xdpyinfo |head
Running as unit: run-u1614.service
Press ^] three times within 1s to disconnect TTY.
name of display: :0
version number: 11.0
vendor string: The X.Org Foundation
你的考试没有 golang
:
sudo systemd-run -t xdpyinfo
Running as unit: run-u2876.service
Press ^] three times within 1s to disconnect TTY.
/usr/bin/xdpyinfo: unable to open display "".