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:
- Login via
ssh root@zynthian.local
- Run
crontab -e
- 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
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
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.
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
Hi @riban, sorry for being vague, it was not intentional, I thought I gave just enough explanation without writing an essay
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
Regards!
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,
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
Iāll try using zynthian as it was meant to be used for now
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,
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.
Thatās an explanation Iām sure to understand:)) Iāll try it out, thanks!
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.