Вопрос или проблема
Я пытаюсь взаимодействовать с сервисом уведомлений через DBus, чтобы отправить уведомление, вручную отправляя сообщения в его назначение. Я сделаю вызов метода Notify
интерфейса org.freedesktop.Notifications
, который имеет следующую сигнатуру:
.Notify method susssasa{sv}i u -
Я застрял на этапе, где мне нужно предоставить массив типа string
и variant
. Но согласно странице man для dbus-send
<contents> ::= <item> | <container> [ <item> | <container>...]
<item> ::= <type>:<value>
<container> ::= <array> | <dict> | <variant>
<array> ::= array:<type>:<value>[,<value>...]
<dict> ::= dict:<type>:<type>:<key>,<value>[,<key>,<value>...]
<variant> ::= variant:<type>:<value>
<type> ::= string | int16 | uint16 | int32 | uint32 | int64 | uint64 | double | byte | boolean | objpath
<array>
принимает <type>
, а не <container>
, к которому принадлежит <variant>
. Поэтому я получаю ошибку.
$ dbus-send --session --print-reply --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.Notify \
string:'me' \
uint32:0 \
string:"hello world" \
string:"" \
string:"" \
dict:string:variant:'urgency',byte:1
dbus-send: Неизвестный тип "variant"
В чем синтаксис сигнатуры a{sv}
?
Синтаксис действительно таков: dict:string:variant:'urgency',byte:1
, но он реализован только в ‘dbus’ 1.15.0 или позже, который в настоящее время является “веткой разработки” ‘dbus’ и еще не найден ни в одной дистрибуции.
Я бы вместо этого порекомендовал либо busctl
(systemd), либо gdbus
(GLib2):
busctl call --user org.freedesktop.Notifications \
/org/freedesktop/Notifications \
org.freedesktop.Notifications Notify \
susssasa{sv}i \
"me" \
0 \
"hello world" \
"" \
"" \
0 \
1 "urgency" y 1 \
0
В busctl сигнатура указывается заранее (как это было бы в самом сообщении D-Bus на проводе) с последующими всеми параметрами, например, ssu "hello" "world" 123
; только параметры типа variant немедленно предшествуют своему фактическому типу. Поскольку нет разделителей, массив или словарь указываются сначала с длиной, за которой следуют их значения или пары ключ/значение.
gdbus call -e -d org.freedesktop.Notifications \
-o /org/freedesktop/Notifications \
-m org.freedesktop.Notifications.Notify \
"me" \
0 \
"hello world" \
"" \
"" \
"[]" \
"{'urgency': <byte 1>}" \
0
gdbus в общем случае ожидает синтаксиса текстового формата GVariant от GNOME, хотя как ярлык он автоматически определит сигнатуру метода и примет обычные строки – но только если они являются отдельным параметром, тогда как в других случаях строки необходимо заключать в кавычки внутри аргумента, например, "'hello'"
для строкового параметра (или даже как "@s 'hello'"
, если вы хотите быть действительно точными), или "<'hello'>"
для варианта (строка). В словаре это будет выглядеть как "{'key': <'value'>}"
.
Ответ или решение
Межпроцессное взаимодействие через D-Bus: Отправка уведомлений с использованием dbus-send
Ваша задача состоит в том, чтобы отправлять уведомления через систему уведомлений D-Bus, используя метод Notify
интерфейса org.freedesktop.Notifications
. При этом вы столкнулись с трудностью при передаче аргументов с использованием формата a{sv}
для словаря в команде dbus-send
. Давайте подробно рассмотрим, как корректно сделать этот вызов.
Понимание сигнатуры метода
Метод Notify
имеет следующую сигнатуру:
Notify method susssasa{sv}i u
- susss – первые четыре параметра представляют собой строки (
string
). - a – указывает на массив.
- s – строка, которая определяет содержимое массива.
- a{sv} – словарь, где ключи являются строками, а значения – вариантами (
variant
), которые могут представлять различные типы данных. - i – целое число (
int32
). - u – неотрицательное целое число (
uint32
).
Правильное использование dbus-send
На данный момент, dbus-send
может не поддерживать тип variant
в словарях корректно, что вызывает ошибку. В версиях dbus
ниже 1.15.0 такой функционал отсутствует, что объясняет проблему, с которой вы столкнулись.
Однако, для отправки уведомлений, вы можете воспользоваться альтернативными инструментами, такими как busctl
или gdbus
, которые обеспечивают большую гибкость и поддержку всех необходимых типов данных.
Пример использования busctl
Вот как можно реализовать вызов метода Notify
с использованием busctl
:
busctl call --user org.freedesktop.Notifications \
/org/freedesktop/Notifications \
org.freedesktop.Notifications.Notify \
susssasa{sv}i \
"me" \
0 \
"hello world" \
"" \
"" \
0 \
1 "urgency" y 1 \
0
Пример использования gdbus
Альтернативно, использование gdbus
может выглядеть следующим образом:
gdbus call -e -d org.freedesktop.Notifications \
-o /org/freedesktop/Notifications \
-m org.freedesktop.Notifications.Notify \
"me" \
0 \
"hello world" \
"" \
"" \
"[]" \
"{'urgency': <byte 1>}" \
0
В gdbus
вы можете использовать текстовый формат GVariant для передачи данных. Важно отметить, что в случае использования gdbus
, строковые параметры должны быть заключены в кавычки, если они являются частью более сложной структуры.
Заключение
Таким образом, для взаимодействия с сервисом уведомлений через D-Bus и передачи необходимых данных в формате a{sv}
, рекомендуется использовать busctl
или gdbus
. Эти инструменты обеспечивают необходимую поддержку для передачи более сложных типов данных, включая словари и массивы. Если у вас остались вопросы или потребности в дополнительной помощи, не стесняйтесь обращаться за разъяснениями.