Run bash script at startup

Hi! I have a kind of a basic question - how to run a bash script automatically once allother processes have started? I tried the usual ways to do it in Linux, but none of them seem to work.

Hi @srl0

easiest way:

  1. Login via ssh root@zynthian.local
  2. Run crontab -e
  3. Add a line like this:
    @reboot /my/script/here.sh

After next reboot your script should be started from cron once at startup.

Complex way: write a service for systemd

Hth Holger

Hi @C0d3man, thank you for the reply
I tried both ways, but none of them seem to work for me :confused:

This should work for you

But just in case your script need to keep running, add an ā€˜&ā€™ at the end of the line to background it.
eg
/usr/local/bin/myscript.sh &
before the end exit 0 in /etc/rc.local

It didnā€™t work, now my zynthian wonā€™t turn on :sleepy:
Iā€™ll just flash the sd again, thank you anyway for your help

Maybe you can give an idea of what you want to achieve, rather than how you want to achieve it. Such context may inform this discussion. There are lots of ways to start processes running at various times in a boot sequence. Zynthian uses systemd (Debianā€™s service manager) to launch various services, including the zynthian main (Python) application which itself controls some services. Without an understanding of what happens when and what you want to do, when and why, it is challenging suggest a solution.

2 Likes

Hello, I had asked myself the same question for the execution of a script when the machine is turned off, in particular to make a LED flash and then for it to turn off completely in order to be sure that the zynthian is properly stopped before cutting the power (I succeeded of course)

I will give you an example, but for turning on the computer.

I will give an example as if I wanted to re-enable /etc/rc.local with systemd.
Your bash script will be written in this file

Create your /etc/rc.local file

ex :
#nano /etc/rc.local

#!/bin/sh
touch /tmp/toto
exit 0

Save this file (type (Ctrl x then y and the enter key)

Give it execution rights:
#chmod +x /etc/rc.local

example for rc.local file:

#nano /etc/systemd/system/rc-local.service

[Unit]
Description=/etc/rc.local Compatibility
ConditionFileIsExecutable=/etc/rc.local

[Service]
Type=simple
ExecStart=/etc/rc.local

[Install]
WantedBy=multi-user.target

Save this file and leave it with the default rights.

Next, we will run the service:
#systemctl start rc-local.service

If all went well, you should find the file /tmp/toto

To have the /etc/rc.local script run at every startup, you must activate it. To do this, run the command:
#systemctl enable rc-local.service

There you go, all you have to do is adapt your /etc/rc.local to your liking and restart your machine.

Enjoy

2 Likes

Hi @riban, sorry for being vague, it was not intentional, I thought I gave just enough explanation without writing an essay :slight_smile:
What Iā€™m trying to do is run a bash script after everything else has started. When I execute my script through ssh it works, but I would like to get rid of that step - I would like to have it run automatically. Thatā€™s the short version, and I think thatā€™s enough explanation for what I need.

But, I can get more precise and Iā€™ll try to explain as best as I can.
In my script I have two lines of code:
I run jack_connect in order to connect MIDI Through virtual port as input;
Then I run a python script that uses pynput and rtmidi to convert keyboard strokes to appropirate MIDI messages (mainly note-on/off and CC). They are sent through the virtual MIDI port.

Iā€™m sure there are countless more elegant ways to achieve this, but this is what I came up with and what I found out that works :))
And thank you again for assisting me in this endeavour, Iā€™m aware that itā€™s not an offically supported thing that Iā€™m trying to achieve.

Thank you, @Melsiar, I will try that

I just added a hook to easing things to those who want to run a user script on boot.
You simply need to put your script in this file:

/zynthian/config/user_config.sh

and give it execution permissions.

It will be executed on every boot before audio subsystem is started.

Update and test, please :wink:

Regards!

2 Likes

I specifically disabled midi through virtual port from appearing in the routing list because it carries the risk of howl-round (positive feedback). Your solution to this issue is indeed a folly of your own invention. There may be benefit in adding a feature request to the issue tracker that describes what you want to do (and why) so that it may be considered as an official implementation.

You could add a service that runs after zynthian has started (by making zynthian service a dependancy) but be aware that zynthian has master control of routing so your manual routes may be undone. The zynthian midi router tries to avoid this but also pays specific attention to this through port so may interfere with your workflow. (I havenā€™t checked the source but @jofemodo and I wrote it so it is fairly clear in my mind.)

It seems that @srl0 wants to route in the jack graph so would want to run after audio subsystem has started.

A new service should be deployed for running after starting audio subsystem. I was profiting of the current ā€œconfig-on-bootā€ service that runs this script on every boot:

#!/bin/bash

BOOT_CONFIG_FILE="/boot/zynthian_envars.sh"
UPDATE_SYS_FLAG_FILE="/zynthian_update_sys"
USER_CONFIG_SCRIPT="/zynthian/config/user_config.sh"

function post_config() {
	rm -rf $ZYNTHIAN_DIR/zyncoder/build
	rm -rf $ZYNTHIAN_CONFIG_DIR/img
	rm -f $UPDATE_SYS_FLAG_FILE
}

# If "zynthian_envars.sh" exist on "/boot" directory, update zynthian config with it ...
if [ -f $BOOT_CONFIG_FILE ]; then
	echo "Found On-Boot config file! Updating Zynthian config ..."
	$ZYNTHIAN_SYS_DIR/sbin/update_envars.py $BOOT_CONFIG_FILE
	post_config
	exit
fi

# If flag-file does exist, call update_zynthian_sys.sh and remove flag ...
if [ -f $UPDATE_SYS_FLAG_FILE ]; then
	echo "Found Config-On-Boot flag! Updating Zynthian config ..."
	$ZYNTHIAN_SYS_DIR/scripts/update_zynthian_sys.sh
	$ZYNTHIAN_SYS_DIR/sbin/zynthian_post_config.sh
	post_config
	exit
fi

# Run user config script if it exists
if [ -f $USER_CONFIG_SCRIPT ]; then
	$USER_CONFIG_SCRIPT
fi

I will consider to add a post-jackd service, but you can try some of this alternate solutions.

You could add a generous sleep on the user_config.sh script or simply wait for jack to be active:

/usr/bin/jack_wait -w

Or wait for the zynthian UI to be ready with something like this:

while [[ "$(pgrep -f zynthian_main.py)" == "" ]]; do
     sleep 0.1
done

Regards,

1 Like

Thank you @riban and @jofemodo for helping me in this. It seems I need a lot more to learn about systemd services and how zynthian uses them before I try something this advanced.
It seemed easy in my head when I started the project :melting_face:
Iā€™ll try using zynthian as it was meant to be used for now :pray:

Ohhh! Itā€™s not really advanced. You simply create this file:

/zynthian/config/user_config.sh

with this content:

#!/bin/bash

# Wait until zynthian-ui is loaded
while [[ "$(pgrep -f zynthian_main.py)" == "" ]]; do
     sleep 0.1
done

# You code here!!!

Donā€™t forget to give the right permissions to the file:

chmod a+x /zynthian/config/user_config.sh

And thatā€™s all!

Best regards,

3 Likes

This is also why itā€™s good to tell what youā€™re trying to do. Thereā€™s no guarantee rc.local would run after jackd starts.

1 Like

Thatā€™s an explanation Iā€™m sure to understand:)) Iā€™ll try it out, thanks! :pray:

1 Like

Like @srl0 Iā€™m trying to run a script on startup and was happy to find this discussion. Unfortunately the code suggested by @jofemodo to wait for the Zynthian UI to start seems to actually prevent the UI from starting so my code never runs. Iā€™m using a DIY system running Oram on a Pi5 with the latest update as of today.

Welcome @rocketmanrc.

You would have to start the script in the background, e.g. by appending & to the end of the command to launch the script.

I was trying the suggested code for user_config.sh as is with no code of my own and it appears to prevent the UI startup. Iā€™ve found where user_config.sh is called and added the & to that call which then prevents the UI from not starting but then when I add anything to to user_config after that such as echo ā€œtestā€ > /tmp/test.txt that never gets executed. I donā€™t have enough knownledge of the full system to look beyond that.