Кажется, я решил ее для screen
...
Сначала я удалил этот параметр Restart=always
.
Чтобы все заработало, мне также пришлось добавить RemainAfterExit=True
.
Со старыми сценариями инициализации было понятно, где взять код. Я действительно не знаю, где правильно разместить остальную часть кода. Должен ли я просто вызвать свой скрипт из ExecStart=
?
Мои дополнительные выводы во время обучения.
Есть хороший вопрос (Я имел в виду, что мне тоже было интересно ), как реализовать проверку состояния-пользовательское сообщение о состоянии systemd?
Короткий ответ: он работает (каким-то образом )из коробки = вам не нужно особо заботиться.
Итак, для моей тестовой службы экрана _я могу позвонить systemctl status test_screen.service
и получить
● test_screen.service - Testing `screen` service
Loaded: loaded (/etc/systemd/system/test_screen.service; disabled; vendor preset: disabled)
Active: active (running) since Wed 2017-09-20 12:48:34 CEST; 1s ago
Process: 36633 ExecStart=/bin/screen -d -m -S test_screen (code=exited, status=0/SUCCESS)
Main PID: 36634 (screen)
CGroup: /system.slice/test_screen.service
├─36634 /bin/SCREEN -d -m -S test_screen
└─36635 /bin/sh
Sep 20 12:48:34 somehostname systemd[1]: Starting Testing `screen` service...
Sep 20 12:48:34 somehostname systemd[1]: Started Testing `screen` service.
...странно то, что когда я останавливаю его, для статуса я получаю отказ:
● test_screen.service - Testing `screen` service
Loaded: loaded (/etc/systemd/system/test_screen.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Wed 2017-09-20 12:51:00 CEST; 1s ago
Process: 36805 ExecStop=/bin/screen -S test_screen -X quit (code=exited, status=0/SUCCESS)
Process: 36633 ExecStart=/bin/screen -d -m -S test_screen (code=exited, status=0/SUCCESS)
Main PID: 36634 (code=exited, status=1/FAILURE)
Sep 20 12:48:34 somehostname systemd[1]: Starting Testing `screen` service...
Sep 20 12:48:34 somehostname systemd[1]: Started Testing `screen` service.
Sep 20 12:51:00 somehostname systemd[1]: Stopping Testing `screen` service...
Sep 20 12:51:00 somehostname systemd[1]: test_screen.service: main process exited, code=exited, status=1/FAILURE
Sep 20 12:51:00 somehostname systemd[1]: Stopped Testing `screen` service.
Sep 20 12:51:00 somehostname systemd[1]: Unit test_screen.service entered failed state.
Sep 20 12:51:00 somehostname systemd[1]: test_screen.service failed.
, чтобы преодолеть это, мне нужно было RemainAfterExit=True
(, потому что я попробовал предложение иметь Type=forking
и закомментировал этот вариант RemainAfterExit
).
У меня была проблема, которую я не могу воспроизвести сейчас -когда я попытался systemctl start
ответ был что-то вроде "Нет файла модуля", поэтому мне было интересно, нужно ли как-то регистрировать его.
Нет, не нужно. Вы можете выполнить systemctl list-unit-files --type=service
, и вы должны увидеть там свой отряд. Моя проблема заключалась в том, что параметр ExecStart
был неправильным. Когда я попробовал то же самое, теперь мне стало легче понять сообщение:
$ systemctl start test_screen.service
Job for test_screen.service failed because the control process exited with error code. See "systemctl status test_screen.service" and "journalctl -xe" for details.
$ systemctl status test_screen.service
● test_screen.service - Testing `screen` service
Loaded: loaded (/etc/systemd/system/test_screen.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Wed 2017-09-20 12:55:53 CEST; 1min 3s ago
Process: 37344 ExecStart=/bin/screen2 -d -m -S test_screen (code=exited, status=203/EXEC)
Main PID: 36634 (code=exited, status=1/FAILURE)
Sep 20 12:55:53 somehostname systemd[1]: Starting Testing `screen` service...
Sep 20 12:55:53 somehostname systemd[37344]: Failed at step EXEC spawning /bin/screen2: No such file or directory
Sep 20 12:55:53 somehostname systemd[1]: test_screen.service: control process exited, code=exited status=203
Sep 20 12:55:53 somehostname systemd[1]: Failed to start Testing `screen` service.
Sep 20 12:55:53 somehostname systemd[1]: Unit test_screen.service entered failed state.
Sep 20 12:55:53 somehostname systemd[1]: test_screen.service failed.
Я попытался модифицировать свой тестовый _экран для вызова скрипта
$ cat /etc/systemd/system/test_screen_script.service
[Unit]
Description=Testing `screen` service
[Service]
Type=forking
ExecStart=/root/test_screen_start.sh
ExecStop=/root/test_screen_stop.sh
#Environment=
#Restart=always
RemainAfterExit=True
[Install]
WantedBy=default.target
в то время как скрипты просто обертываются для предыдущих вызовов
$ cat /root/test_screen_start.sh
/bin/screen -d -m -S test_screen
$ cat /root/test_screen_stop.sh
/bin/screen -S test_screen -X quit
когда я это сделал, он не запускается:
$ systemctl start test_screen_script
Job for test_screen_script.service failed because the control process exited with error code. See "systemctl status test_screen_script.service" and "journalctl -xe" for details.
$ systemctl status test_screen_script.service
● test_screen_script.service - Testing `screen` service
Loaded: loaded (/etc/systemd/system/test_screen_script.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Wed 2017-09-20 15:47:59 CEST; 8s ago
Process: 63582 ExecStart=/root/test_screen_start.sh (code=exited, status=203/EXEC)
Main PID: 60698 (code=exited, status=0/SUCCESS)
Sep 20 15:47:59 somehostname systemd[1]: Starting Testing `screen` service...
Sep 20 15:47:59 somehostname systemd[63582]: Failed at step EXEC spawning /root/test_screen_start.sh: Exec format error
Sep 20 15:47:59 somehostname systemd[1]: test_screen_script.service: control process exited, code=exited status=203
Sep 20 15:47:59 somehostname systemd[1]: Failed to start Testing `screen` service.
Sep 20 15:47:59 somehostname systemd[1]: Unit test_screen_script.service entered failed state.
Sep 20 15:47:59 somehostname systemd[1]: test_screen_script.service failed.
Было бы хорошо, если бы кто-нибудь мог описать причину. Исправление для этого состоит в том, чтобы добавить #!/bin/bash
.
list-unit-files
здесь:https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-unitsТри пути:
Во-первых, ваш xargs
способ терпит неудачу, потому что вы даете dirname
более одного имени пути за раз. Вместо этого передавайте ему пути один за другим:
find. -type f -name '*_test.go' -print0 | xargs -0 -r -I {} dirname {}
-print0
с find
и -0
с xargs
передают пути как список с нулевыми разделителями -, а не как список с разделителями новой строки -. Опция -r
для xargs
гарантирует, что dirname
не будет запущен, если нет входных данных от find
.
Если вы знаете, что ваши имена файлов не содержат встроенных символов новой строки:
find. -type f -name '*_test.go' | xargs -r -I {} dirname {}
Во-вторых, вызовите внутристрочный -сценарий оболочки с find
, который запускает dirname
файлы один за другим:
find. -type f -name '*_test.go' -exec sh -c '
for pathname do
dirname "$pathname"
done' sh {} +
Либо не вызывать dirname
, а использовать подстановку параметров в цикле (быстрее):
find. -type f -name '*_test.go' -exec sh -c '
for pathname do
printf "%s\n" "${pathname%/*}"
done' sh {} +
В-третьих, если вы используете GNU find
, используйте его-printf
:
find. -type f -name '*_test.go' -printf '%h\n'
Наконец, если вы используетеzsh
:
print -rC1 --./**/*_test.go(.ND:h)
Модификатор glob (.ND:h)
запрашивает предыдущий шаблон расширения только для обычных файлов(.
)и ничего не расширяет, если нет файлов, соответствующих шаблону (N
, например nullglob
в bash
), а также включать скрытые имена (D
, например dotglob
вbash
). :h
в конце приводит к возврату «заголовка» каждого подходящего пути (, т. е. части каталога пути без имени файла ).
Вы можете сделать что-то подобное в bash
с таким циклом:
shopt -s globstar nullglob dotglob
for pathname in./**/*_test.go; do
if [[ -f $pathname ]] && [[ ! -h $pathname ]]; then
printf '%s\n' "${pathname%/*}"
fi
done