📜 ⬆️ ⬇️

The script that handles system events with DBus

Dbus is a means of interprocess communication. In other words, a tool that allows one program to “give orders” to another program.
In the network it is easy to find examples of how to manage various programs from the command line using DBus. But the topic of how to track signals from other programs is poorly disclosed. In this article I want to correct this injustice and analyze the example of processing events received from the system through Dbus.

In addition to bindings to programming languages ​​for Dbus, there are a number of console programs that allow it to be used from the command line.

Also, when working with DBus, the qdbusviewer program is of interest - a graphical application that allows you to study existing programs in the system with DBus support.

And so, the promised example.


Task: write a script that, when establishing a connection to the Internet, the YandexDisk client will start.
We start qdbusviewer and look for which service can report on network status changes. On the System bus tab, we see the org.freedesktop.NetworkManager service. If we pass along the path / org / freedesktop / NetworkManager in this service, we will find an object implementing the org.freedesktop.NetworkManager interface. There is a StateChanged signal on this interface. Check: Right click on the signal and select Connect. We disconnect, we connect the network interface, we see the coming signals informing the status of a network. What we need.
Now we will achieve the same result on the command line. We will use the dbus-monitor command. Enter in the command line:
dbus-monitor --system "sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager, member=StateChanged" 

Here the option --system is an instruction to listen to the system bus. In quotes the filter of the signal of interest is indicated. The org.freedesktop.NetworkManager service, path / org / freedesktop / NetworkManager, and the StateChanged signal.
We disconnect, we connect the network interface. In the process of changing the state of the network, all new lines are displayed on the console:
 signal sender=org.freedesktop.DBus -> dest=:1.540 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired string ":1.540" signal sender=:1.2 -> dest=(null destination) serial=1870 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged uint32 20 signal sender=:1.2 -> dest=(null destination) serial=1883 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged uint32 40 signal sender=:1.2 -> dest=(null destination) serial=1899 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged uint32 70 

On each received signal is displayed on 2 lines. The first with the description of the signal, the second with the value of the argument. By the way, if the signal has more arguments, then there will be more lines.
Experimentally determined, the status of the connected network corresponds to the value 70.
Strictly speaking, the values ​​of the constants should be viewed in the NM_STATE documentation (thanks to avalak for the link)

Now we need to process the received signals and form a command to start the YandexDisk. Enter in the command line:
 dbus-monitor --system "sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager, member=StateChanged" | sed -u -n 's/ uint32 70/yandex-disk start/p' 

We have added the previous command line | sed -u -n 's / uint32 70 / yandex-disk start / p'. Here we process every line received from dbus-monitor using the sed program. The -u option tells sed to output the result immediately, without putting it into the buffer. The option -n - do not display anything until there is an explicit command. In single quotes, a command is specified to sed: replace the phrase "uint32 70" with the phrase "yandex-disk start" and output the result. This command converts text.
 signal sender=org.freedesktop.DBus -> dest=:1.540 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired string ":1.540" signal sender=:1.2 -> dest=(null destination) serial=1870 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged uint32 20 signal sender=:1.2 -> dest=(null destination) serial=1883 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged uint32 40 signal sender=:1.2 -> dest=(null destination) serial=1899 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged uint32 70 signal sender=:1.2 -> dest=(null destination) serial=1870 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged uint32 20 signal sender=:1.2 -> dest=(null destination) serial=1883 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged uint32 40 signal sender=:1.2 -> dest=(null destination) serial=1899 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged uint32 70 

at
 yandex-disk start yandex-disk start 

That is, at each connection to the network, the yandex-disk start command is formed.
')
Finally the final version:
 dbus-monitor --system "sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager, member=StateChanged" | sed -u -n 's/ uint32 70/yandex-disk start/p' | sh 

Sends generated commands to start the Yandex disk for execution.

Save to file
 #!/bin/bash dbus-monitor --system "sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager, member=StateChanged" | sed -u -n 's/ uint32 70/yandex-disk start/p' | sh 

Making the file executable. And add to autostart. Now, when connecting to the Internet, the YandexDisk client will automatically start.

Similarly, you can process the signals of any applications that support DBus.

The article considered the possibility of automating the processing of signals coming from various applications using DBus. The dbus-monitor program is used to monitor signals in the console. This program allows you to catch all the signals of all services, and filter only what interests us.
A few examples:

dbus-monitor for each received signal displays several lines. In the first description of the signal, in the subsequent values ​​of the arguments.
Next, we process the received signals as we please.

Source: https://habr.com/ru/post/223135/


All Articles