Systemd.path :Как определить, какой путь изменен?

Ваш код,

awk -F '\t' 'BEGIN{OFS=FS} NR==FNR {a[$1]=$1; next} $3 in a {print $1}' File2 File1

никогда не мог вывести два столбца, так как printв конце выводит только первый столбец из File1.

Вы почти у цели. Вам нужно сделать одну крошечную настройку, которая должна фактически вывести отсутствующее поле :

.

awk -F '\t' 'BEGIN{OFS=FS} NR==FNR {a[$1]=$1; next} $3 in a {print $3, $1}' File2 File1
                                                                   ^^^
                                                                 add this

Запуск этого на ваших данных должен произвести

MSTRG.1.1 a
MSTRG.3.1 d

Для больших наборов данных см. решение steve , которое более эффективно использует память.

3
28.07.2020, 03:57
1 ответ

Поиграв немного, я обнаружил, что самый простой способ — использовать один файл *.pathдля каждого пути и шаблонировать каждый путь в один файл *@.service. Вот что-то на вашем примере:

$ systemctl --user cat 123* *.path
# /home/stew/.config/systemd/user/123@.service
[Service]
Type=oneshot
ExecStart=/bin/echo %I

# /home/stew/.config/systemd/user/abc.path
[Path]
PathChanged=/a/b/c
Unit=123@-a-b-c.service

# /home/stew/.config/systemd/user/foobar.path
[Path]
PathChanged=/foo/bar
Unit=123@-foo-bar.service

# /home/stew/.config/systemd/user/xyz.path
[Path]
PathChanged=/x/y/z
Unit=123@-x-y-z.service

*.serviceможет получить доступ к пути через спецификатор%I

Чтобы получить Unit=имена, я использовал systemd -escape:

$ systemd-escape --template=123@.service \
      '/x/y/z' \
      '/a/b/c' \
      '/foo/bar'
123@-x-y-z.service 123@a-b-c.service 123@-foo-bar.service

Соответствующие справочные страницы:

Если вам интересно, есть ли более простое решение, вот что я пробовал:


Эксперимент 1

Гипотеза :Это переменная окружения.

systemd.exec (5)дает список переменных окружения. Возможно, установлено что-то вроде $RUNTIME_DIRECTORYили $LISTEN_FDS.

Настройка эксперимента:

$ mkdir /home/stew/systemdpath
$ systemctl --user cat simplepath.*
# /home/stew/.config/systemd/user/simplepath.path
[Unit]
Description=Path testing

[Path]
DirectoryNotEmpty=/home/stew/systemdpath

# /home/stew/.config/systemd/user/simplepath.service
[Unit]
Description=Path testing unit

[Service]
Type=oneshot
ExecStart=/usr/bin/env
$ systemctl --user start simplepath.path

Результаты эксперимента:

$ touch ~/systemdpath/file
$ journalctl --user simplepath.service
Jul 28 08:26:16 stewbian systemd[31634]: Starting Path testing unit...
Jul 28 08:26:16 stewbian env[334512]: HOME=/home/stew
Jul 28 08:26:16 stewbian env[334512]: LANG=en_GB.UTF-8
Jul 28 08:26:16 stewbian env[334512]: LANGUAGE=en_GB:en
Jul 28 08:26:16 stewbian env[334512]: LOGNAME=stew
Jul 28 08:26:16 stewbian env[334512]: PATH=/home/stew/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
Jul 28 08:26:16 stewbian env[334512]: SHELL=/bin/bash
Jul 28 08:26:16 stewbian env[334512]: USER=stew
Jul 28 08:26:16 stewbian env[334512]: XDG_RUNTIME_DIR=/run/user/1000
Jul 28 08:26:16 stewbian env[334512]: GTK_MODULES=gail:atk-bridge
Jul 28 08:26:16 stewbian env[334512]: QT_ACCESSIBILITY=1
Jul 28 08:26:16 stewbian env[334512]: DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
Jul 28 08:26:16 stewbian env[334512]: DESKTOP_SESSION=/usr/share/xsessions/i3
Jul 28 08:26:16 stewbian env[334512]: DISPLAY=:0
Jul 28 08:26:16 stewbian env[334512]: GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1
Jul 28 08:26:16 stewbian env[334512]: PAM_KWALLET5_LOGIN=/run/user/1000/kwallet5.socket
Jul 28 08:26:16 stewbian env[334512]: PWD=/home/stew
Jul 28 08:26:16 stewbian env[334512]: SHLVL=1
Jul 28 08:26:16 stewbian env[334512]: XAUTHORITY=/home/stew/.Xauthority
Jul 28 08:26:16 stewbian env[334512]: XDG_CURRENT_DESKTOP=i3
Jul 28 08:26:16 stewbian env[334512]: XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
Jul 28 08:26:16 stewbian env[334512]: XDG_SESSION_CLASS=user
Jul 28 08:26:16 stewbian env[334512]: XDG_SESSION_DESKTOP=i3
Jul 28 08:26:16 stewbian env[334512]: XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session5
Jul 28 08:26:16 stewbian env[334512]: XDG_SESSION_TYPE=x11
Jul 28 08:26:16 stewbian env[334512]: _=/usr/bin/dbus-update-activation-environment
Jul 28 08:26:16 stewbian env[334512]: MANAGERPID=31634
Jul 28 08:26:16 stewbian env[334512]: INVOCATION_ID=837f6b2e56b543c9b51cda4ee8952fa8
Jul 28 08:26:16 stewbian env[334512]: JOURNAL_STREAM=8:21581980
Jul 28 08:26:16 stewbian systemd[31634]: simplepath.service: Succeeded.
Jul 28 08:26:16 stewbian systemd[31634]: Finished Path testing unit

Заключение:

Systemd не помещает путь в переменную среды.


Эксперимент 2

Гипотеза :Она может быть шаблонной

Думая о $LISTEN_FDS, есть некоторые параллели между сокетом и путями. Сокеты создаются по шаблону при установке Accept=yes, что, если мы попробуем сделать это с путями?

Исходная настройка:

$ systemctl --user cat simplepath*
# /home/stew/.config/systemd/user/simplepath.path
[Unit]
Description=Path testing

[Path]
DirectoryNotEmpty=/home/stew/systemdpath
Unit=simplepath@.service

# /home/stew/.config/systemd/user/simplepath@.service
[Unit]
Description=Path testing unit

[Service]
Type=oneshot
ExecStart=/bin/echo %i

Результаты эксперимента:

$ systemctl --user start simplepath.path
$ touch ~/systemdpath/file
$ journalctl --user --since "5 minutes ago"
Jul 28 09:14:25 stewbian systemd[31634]: Starting Path testing unit...
Jul 28 09:14:25 stewbian echo[336171]: simplepath
Jul 28 09:14:25 stewbian systemd[31634]: simplepath@simplepath.service: Succeeded.

Заключение

Экземпляром, эхо-отображенным в службе, было имя самой службы. Это не помогает.


Эксперимент 3

Гипотеза :Каждый путь может иметь свой собственный файл и шаблон сервиса

Настройка эксперимента:

$ mkdir ~/path1
$ mkdir ~/path2
$ systemctl --user cat path*
# /home/stew/.config/systemd/user/path1.path
[Unit]
Description=Path1 testing

[Path]
DirectoryNotEmpty=%h/path1
Unit=paths@path1.service

# /home/stew/.config/systemd/user/path2.path
[Unit]
Description=Path2 testing

[Path]
DirectoryNotEmpty=%h/path2
Unit=paths@path2.service

# /home/stew/.config/systemd/user/paths@.service
[Unit]
Description=Path testing unit

[Service]
Type=oneshot
ExecStart=/bin/echo %h/%i
$ systemctl --user start path1.path path2.path

Эксперимент:

$ touch ~/path1
$ touch ~/path2
$ journalctl --user --since "5 minutes ago"
Jul 28 09:43:45 stewbian systemd[31634]: Starting Path testing unit...
Jul 28 09:43:45 stewbian echo[336517]: /home/stew/path1
Jul 28 09:43:45 stewbian systemd[31634]: paths@path1.service: Succeeded.
Jul 28 09:43:45 stewbian systemd[31634]: Finished Path testing unit.
Jul 28 09:43:50 stewbian systemd[31634]: Starting Path testing unit...
Jul 28 09:43:50 stewbian echo[336519]: /home/stew/path2
Jul 28 09:43:50 stewbian systemd[31634]: paths@path2.service: Succeeded.
Jul 28 09:43:50 stewbian systemd[31634]: Finished Path testing unit.

Заключение

У вас может быть одна шаблонная единица обслуживания, работающая для нескольких единиц пути. Кажется, это самый простой подход.

Проблема, с которой я столкнулся здесь, заключается в том, что служба использует %h, который является домашним каталогом. У меня были проблемы, когда я включал символ /в имена шаблонов. systemd -escape (1 ), кажется, помогает с этим.

11
18.03.2021, 23:16

Теги

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