Как получить имя каталога из пути

Кажется, я решил ее для 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.

Ссылки

-2
20.01.2020, 23:26
1 ответ

Три пути:

Во-первых, ваш 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
3
28.01.2020, 05:15

Теги

Похожие вопросы