Sunday, June 23, 2019

How to create (via installer script) a task that will install my bash script so it runs on DE startup?



I've been reading for the last couple hours about Upstart, .xinitrc, .xsessions, rc.local, /etc/init.d/, /etc/xdg/autostart, @reboot in crontab and so many other things that I'm totally confused!



Here is my bash script. It should start/run after the desktop environment is started and it should continue to run at all times until logout/shutdown. It should start again on reboot. Any time the DE is running, it should run.



#!/bin/bash
while true; do
if [[ -s ~/.updateNotification.txt ]]; then
read MSG < ~/.updateNotification.txt

kdialog --title 'The software has been updated' --msgbox "$MSG"
cat /dev/null > ~/.updateNotification.txt
fi
sleep 3600
done
exit 0


I know zero about using Upstart, but I understand that Upstart is one way to handle this. I'll consider other approaches but most of the things I've been reading about are too complex for me. Furthermore, I can't figure out which approach will meet my requirements (which I'll detail below).




There are two steps in my question:




  1. How to automatically start the script above, as described above.


  2. How to "install" that Upstart task via a bash script (i.e., my "installer").




I assume (or hope) that step 2 is almost trivial once I understand step 1.



I have to support all flavors of Ubuntu desktops. Therefore, the kdialog call above will be replaced. I'm considering easybashgui for this. (Or I could use zenity on gnome DE's.)




My requirements are:




  1. The setup process (installation) must be done via a bash script. I cannot use the GUI method described in the Ubuntu doc AddingProgramToSessionStartup, for example. I must be able to script/automate the setup (installing) process using bash. Currently, it is as simple as having the bash installer script copy the above script into /home/$USER/.kde/Autostart/


  2. The setup process must be universal across Ubuntu derivatives including Unity and KDE and gnome desktops. The same setup script (installer) should run on Linux Mint, Kubuntu, Xbuntu (basically any flavor of Ubuntu and major derivatives such as Linux Mint). For example, we cannot continue to put a script file in /home/$USER/.kde/Autostart/ because that exists only on KDE.


  3. The above script should work for each of the limited flavors we use. Hence our interest in using easybashgui instead of kdialog or zenity. See below.


  4. The installed monitoring script should only be started after the desktop is started since it will display a GUI message to the user if the update is found.



    1. The monitoring script (above) should run without root privileges, of course. But the installer (bash script) can be run as root.



  5. I'm not a real developer or a sysadmin. This is a part time volunteer thing for me, so it needs to be easy/simple. I can write bash scripts and I can program a little, but I know nothing about Upstart or systemd, for example. And, unfortunately, my job doesn't give me time to become an expert on init systems or much of anything else related to development and sysadmin. So I have to stick with simple solutions.




The easybashgui version of the script might look like this:



#!/bin/bash
source easybashgui
while true; do
if [[ -s ~/.updateNotification.txt ]]; then

read MSG < ~/.updateNotification.txt
message "$MSG"
cat /dev/null > ~/.updateNotification.txt
fi
sleep 3600
done
exit 0


Launcher




The tasks in /etc/xdg/autostart are started by the Desktop Environment with the current user's credentials and they can access the GUI, so I think this is the best choice.



File /etc/xdg/autostart/updateNotification.desktop:



[Desktop Entry]
Name=My Update Notification
Exec=updateNotification.sh
Terminal=false
Type=Application

NoDisplay=true





Monitoring script



The monitoring script must be placed in a world accessible location. I recommend /usr/local/bin because messing with files in that directory will not affect the OS. I changed you script a little bit.



File /usr/local/bin/updateNotification.sh:




#!/bin/bash

# Exit if this script is already running.
[[ $(pgrep -c -u $USER -f "^/bin/bash ${0}$") -gt 1 ]] && exit 0

NotifFile=~/.updateNotification.txt

source easybashgui


# Wait some time before starting monitoring the file, so the user doesn't get a popup right after logging in.
sleep 120

while true; do
if [[ -s $NotifFile ]]; then
read MSG < $NotifFile
# Only empty the file if the message is successfully displayed.
message "$MSG" && echo -n > $NotifFile
fi
sleep 3600

done

exit 0


Of course, you'll have to download easybashgui, extract it and install it.



tar xzf easybashgui-8.0.1.tar.gz
cd easybashgui-8.0.1/
sudo make install






Installer



I really like to use bash self-extracting files because the entire installation process can be embeded in a single file. All we have to do is concatenate a pre-built bash header with a tar file.



Before creating the archive make sure all the files are in the place they should be and have the right permissions, in this case:




sudo chown root:root /etc/xdg/autostart/updateNotification.desktop
sudo chown root:root /usr/local/bin/updateNotification.sh
sudo chmod 644 /etc/xdg/autostart/updateNotification.desktop
sudo chmod 755 /usr/local/bin/updateNotification.sh


We can also include easybashgui in the installer. Uncompress easybashgui archive to /tmp:



tar zxf easybashgui-8.0.1.tar.gz -C /tmp



and tar all the required files:



sudo tar zcf MyArchive.tar.gz /etc/xdg/autostart/updateNotification.desktop /usr/local/bin/updateNotification.sh /tmp/easybashgui-8.0.1/


Create the bash header that will uncompress the archive and install easybashgui. File header.sfx:



#!/bin/bash
DATA=`awk '/^__BEGIN_DATA__/ { print NR + 1; exit 0; }' $0`

tail -n+$DATA $0 | tar zx -C /

# Additional installation steps
cd /tmp/easybashgui-8.0.1/
make install

exit 0

# The following line must be the last one. Don't place any character after it.
__BEGIN_DATA__



Finally, join the header and the archive:



cat header.sfx MyArchive.tar.gz > MyInstaller.sh


Now you can copy that installer to another machine, give it execution permission and run sudo ./MyInstaller.sh.







That's it. Hope it helps.


No comments:

Post a Comment

11.10 - Can&#39;t boot from USB after installing Ubuntu

I bought a Samsung series 5 notebook and a very strange thing happened: I installed Ubuntu 11.10 from a usb pen drive but when I restarted (...