Skip to content

Instantly share code, notes, and snippets.

@shellheim
Last active November 12, 2024 11:22
Show Gist options
  • Save shellheim/e35c44ad0426f37550b68ad1082be15c to your computer and use it in GitHub Desktop.
Save shellheim/e35c44ad0426f37550b68ad1082be15c to your computer and use it in GitHub Desktop.
How to Use ydotool on Linux?

How to Use ydotool on Linux.

ydotool requires the program ydotoold to be running in the background. Now to make this easier the developer ships a systemd unit file with the project. If ydotoold isn't running the program won't work.

A systemd unit file basically calls programs in the background which are needed for the OS to run. In this case we will use this file to run ydotoold in the background as soon as we boot our device. If your distro packages ydotool sensibly then the service (the background program run by the file) should already be running.

To check, run:

systemctl status ydotoold.service

This should return something like this :

● ydotool.service - Starts ydotoold service
     Loaded: loaded (/usr/lib/systemd/system/ydotool.service; enabled; preset: disabled)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf
     Active: active (running) since Sun 2024-04-28 14:12:42 IST; 26min ago
   Main PID: 1328 (ydotoold)

If don't see something like 'active (running) since...' then you'll have to start the service. To start it, run :

 systemctl start ydotoold.service

To always run the service at boot time, run :

systemctl enable ydotoold.service

Now, since it's running, let's run a little test to check if yodtool is working as expected. Run :

ydotool type 'Hello World!'

This should make ydotool type 'Hello World!' on the screen.

Ownership and file doesn't exist error

If you are facing an error that's something along the lines of error: /tmp/.ydotool_socket : permission denied or error: /tmp/.ydotool_socket : file not found or file doesn't exist.

This file, /tmp/.ydotool_socket, is a 'socket' file which the ydotoold service needs. By default this file in loacted in /tmp.

To make sure that this is the file used by ydotoold, make an env variable $YDOTOOL_SOCKET with the value of tmp/.ydotool_socket. To do this in bash, go to ~/.bashrc and add this line :

export YDOTOOL_SOCKET=/tmp/.ydotool_socket

If you use another shell like fish and zsh, go ahead and add this variable in your config. Now, try and restart the service again :

systemctl restart ydotoold.service

Now run the test again. There is a chance that this might stil not work. If this is the case, run :

ls -l /tmp/.ydotool_socket

If the output is something along the lines of :

srw-------. 1 root root 0 Apr 28 14:18 /tmp/.ydotool_socket=

Then, you can see that the file is owned by the root user. This means the ydotool command run by your non-root user can't access this file, as a result of which, ydotool won't work. To fix this we need to edit the unit file itself.

Locate the unit file, most probably in /usr/lib/systemd/system, if it's not there and in something like /usr/lib/systemd/user then delete the file under the user sub-directory and create another ydotoold.service file under /usr/lib/systemd/system.

This is because ydotoold needs root privileges to run, running .service files from the /usr/lib/systemd/system directory also requires the same privileges.

So instead of running it with sudo everytime, we will run the file once and ydotoold will acquire the permissions it needs forever.

Now, open the ydotoold.service file in your favorite editor as root (using sudo).

You'll see something like this:

[Unit]
Description=Starts ydotoold service

[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/ydotoold
ExecReload=/usr/bin/kill -HUP $MAINPID
KillMode=process
TimeoutSec=180

[Install]
WantedBy=default.target

The program ydootoold has a flag named --socket-own which decides the ownership of the socket file, this takes in it's value in the format UID:GID, like 1000:1000. To get these values for yourself, run :

echo $(id -u):$(id -g)

For me it's 1000:1000 but it might be different for you.

Now go to the 'ExecStart' line and after /usr/bin/ydotoold, add --socket-own=1000:1000 and save the file. Now this line should look like :

[Unit]
...

[Service]
...
ExecStart=/usr/bin/ydotoold --socket-own=1000:1000
...

[Install]
...

Since you have changed the contents of the unit file, you'll first have to run :

systemctl daemon-reload

Make sure run to run :

sudo rm /tmp/.ydotool_socket

We need to remove the previous socket file before restarting the service because the old socket file will be used, which would still be owned by root. Removing that file results in the creation of a new file owned by your user.

Now finally run :

systemctl restart ydotoold.service

The program should now work as expected. As a test you can run :

ydotool type 'Hello World!'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment