Golang cmd.Output () из exe c .Command () выдает ошибку в службе systemd (ubuntu) - PullRequest
1 голос
/ 16 июня 2020

У меня есть двоичный файл go, который получает отображаемую информацию, используя cmd := exec.Command("xdpyinfo"), а затем вызывает cmd.Output(). Программа работает в терминале как положено. Однако, когда я запускаю это как службу systemd, из cmd.Output() не выводится. У меня программа работает как служба, но вызов cmd.Output () возвращает ошибку.

Я попытался максимально упростить воспроизведение:

У меня есть исполняемый файл go двоичный тест с именем /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.

Шаги, которые я предпринял для запуска службы:

  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))
}

Теперь я начинаю думать, что мне не хватает чего-то более фундаментального.

1 Ответ

0 голосов
/ 16 июня 2020

Вы должны запустить его в своем пользовательском сеансе (который также запустил ваш сеанс 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 "".
...