Ubuntu 14.04 - How do I play an ogg file on shutdown with a script? - bash

So, I'm attempting to have a script play a short ogg file on shutdown/restart but I seem to be having some sort of trouble actually getting it to work. Right now, I have the script in init.d and have symbolic links in rc0.d and rc6.d that all seem to work when manually executed. The script and the links all start with "K99" because the system supposedly proceeds alphabetically through the list and K99 should make it execute at the correct time. (I've tried other things, like K00, K50 and the "S" variations because I saw some other scripts with that; but they didn't seem to change anything.)
#!/bin/sh
## play shutdown sound
pulseaudio --start
echo -e "Shutdown sound script."
/usr/bin/play /home/username/Downloads/sound_file.ogg
sleep 3
The script is pretty simple I think. The ogg file and the script are both at 755 permissions. The file is only about 3s long, so I don't think that's a problem either. Originally, it seemed as if the script wasn't working at all so I added the sleep command. It seems to take about three seconds longer to shut down now, so I think the script IS running, but I have a feeling that Ubuntu is perhaps killing the audio daemon (if there is one?) before the script goes off, but I'm not sure. I've spent a few days trying to figure this seemingly simple thing out. Any ideas?
Sorry if this ends up being trivial, I'm a bit of a novice with Ubuntu system things. (Though I'd be fine with a simple fix! :) )
UPDATE
It works as it should now! After some searching about why the sound might be playing multiple times and especially on startup, I learned a bit more about the upstart system. It looks through the etc/init/ directory and runs the scripts in there on start up. I remembered that I had experimented by putting an upstart script there when the sound was still not playing at all. Apparently I had forgotten to remove it and it was executing on all run levels thus leading to the double shutdown and startup instances. Now it's gone and all is as it should be. (Although now that I've fixed it, I'm a bit sick of hearing the sound and might have to find a new one, lol.) Thanks for the help, all.
TL;DR: Put a script in init.d and symbolically link to etc/rc0.d (and etc/rc6.d if you want it on reboot too). If it plays multiple times, you've probably got a duplicate somewhere it shouldn't be.

To execute a script at shutdown
Put your script in /etc/rc0.d
Make it executable (sudo chmod +x script.sh)
Note: The scripts in this directory are executed in alphabetical
order
PulseAudio
PulseAudio is a sound server. It allows you to do advanced operations on your sound data as it passes between your application and your hardware.
Start PulseAudio at the begging of your script:
pulseaudio --start
Note: You must try/use this commands in your script because starting audio daemon and playing your ogg file is just a matter of time.

Related

SHC converted shell 'Breaks' on system reboot

I am making a public image on AWS and so am required to 'hide' some shell scripts, but still have them freely usable. We're not looking for the utmost security, I understand SHC can be reverted if a user actually wishes to do so, but it's enough for my requirement.
So that's all good! I have a shell, 'test.sh'. I convert it, 'shc -f test.sh'. The output is a .x and a .x.c file. I run './test.sh.x' - It runs exactly as I expect it to.
So far so good...
But if at any point I reboot the instance, then when I try and run './test.sh.x' again it fails and just outputs a load of random binary stuff.
I have absolutely zero idea what is causing this or why it is causing this. The file is not being edited, or moved, or anything.. It just suddenly does not work anymore. Why?? I've searched online but can't seem to find anyone having this same issue, so any help will be massively appreciated.
And to note, a valid alternative that may not result in the same issue (worth testing at least) is most welcome, as I'm not dead-set on using SHC specifically, it's just the only one I know about currently.
Oooookay, well I unfortunately was never able to fix this issue. Even if I install SHC after I create an instance from my own AMI, and then compile the scripts at this point, the scripts only work until I reboot the system and then they no longer work.
So instead I found a different solution using Bash-Obfuscator, installed and run as follows:
dnf -y install npm nodejs
npm install -g bash-obfuscate
bash-obfuscate test_input.sh -o test_output.sh
And that perfectly does what I needed. There was, however, one thing I quickly learned using Bash-Obfuscator which was quite important - Do NOT have 'echo' commands across multiple lines as it will break your script. The following will break when obfuscated using this command:
echo "Hello
World"
But replacing that with this (which is practically the same thing) works perfectly okay (must be some way the parser is coded):
TEST_VAR="Hello
World"
echo "${TEST_VAR}"
Hope this helps anyone in future.

bash script/method that brings down WM/Xorg when a process is done

I'm attempting to make a Linux system that is meant to run a GUI on top of a window manager, as it requires it for inputs from a device to work. I say attempting because I've been trying for several days but I can't get the bash scripting to work no matter what.
My approach is using a bash script that starts an X session using openbox with nothing on it except for the program I want running on top (I don't care which WM, as long as it's a WM that makes the input work, which I've found that both XFWM4 and Openbox do. I'm willing to use any other that will be better if after testing suggestions those also happen to work).
Once the program is closed (by selecting Quit on it) I'm left with the WM still running, which I don't want, it must go down along with the app, so the system returns to lightdm's login screen.
I can't modify what the quit command on it does either; would take a long time recompiling and modifying such a big app for something so trivial. This is why I really need the WM to go down by itself when the app's process is gone.
I've tried using the openbox autostart script and also a custom script that is run using the .desktop file that is found by lightdm. All my attempts end up with a script that simply kills the display right after entering the session.
I just want something simple like this:
#!/bin/bash
openbox &
guiapp; openbox --exit (or killall Xorg whatever)
But this syntax won't work. I've tried using things like pid=$(pgrep guiapp) to make it look for the PID every bunch of seconds and if it's not there, kill the WM or Xorg entirely; but those also didn't work, I don't know if my attempts were bad or what. Sorry I can't put those examples since I didn't make backups of my script attempts and I've been trying for quite a long time without success.
I really hope someone can help me.
I finally got it working! I found a post online that was attempting a similar thing to mine and he did this approach:
in ~/.config/openbox/autostart:
xsetroot -solid black &
gnome-terminal --full-screen --hide-menubar -e guiapp &
/etc/guiapp/Exit.sh &
in /usr/share/xsessions/gui.desktop:
[Desktop Entry]
Name=OpenBox Session
Exec=openbox-session
TryExec=openbox-session
Finally the actual solution in /etc/guiapp/Exit.sh:
#!/bin/bash
until [[ $(pidof guiapp) ]] ; do
sleep 1
done
while [[ $(pidof guiapp) ]] ; do
sleep 1
done
openbox --exit
His task was slightly different but all it took was some slight modification of his exit script to tailor it to what I wanted.
This way, LightDM will run OpenBox with the flag telling it to read the autostart script, and autostart will run both the app and a script that will keep looking for the pid of my app every second, and when it's down, it'll quit OpenBox to the login screen automatically, so I can switch to a different DM. Just how I wanted it!

Bash script file hangs on execute

I just realized that i cannot execute .sh scripts anymore on my debian.
It used to work fine. All .sh files are +x chmodded and used to work fine.
Suddenly, once i execute: ./test.sh system hangs.
I am able to stop this via ctrl+c, but script never executes.
Steps did so far was to restart my VPS.
Any ideas?
I am pretty sure shell scripts are still working on your machine, because if they weren't, you would not be able to complete any boot cycle.
If I suppose you are facing problems with your homemade scripts, then you should probably check your shebang line (#!/bin/sh for example) to see if anything unusual was used there.
New scripts are using a dispatcher to interpreters:
`#!/usr/bin/env bash` #lends you some flexibility on different systems
`#!/usr/bin/bash` #gives you explicit control on a given system of what executable is called
The difference between “#! /usr/bin/env bash” and “#! /usr/bin/bash”?

make a program reload an already opened file on file change

I need to play a .swf file then when the file is changed to reload the player with new content. Sadly, my program of choice does not do monitor files for changes. I came up with a bit convoluted solution:
sudo apt-get install incron gtk-gnash
echo "my_username" | sudo tee -a /etc/incron.allow # allow my_username to run incron
incrontab -e
add the following to incrontab:
/home/my_username/path/myfile.swf IN_MODIFY /home/my_username/path/run.sh
and the run.sh contains: ( also chmod 700 run.sh)
#!/bin/sh
killall gtk-gnash
gtk-gnash /home/my_username/path/myfile.swf
As you can see this is far from elegant. How else could I go about this?
This is on Ubuntu 12.04 if that matters for you. This is a duplicate of my own question on askubuntu
EDIT: clarification, I chose to use gtk-gnash, a standalone player, this is not required, a web browser would do too but seems not necessary
What you're describing is the job of a File Alteration Monitor.
First off, your existing "incrontab" solution is a good starting point, given that you're launching things from shell. The fact that incrontab is an inotify(7)-based solution is a huge plus. It means that you aren't polling, which saves CPU.
You're asking for shell and system-level solutions, and I'm not a Flash programmer, so I'll stick to your question, though I think a better solution would be to create a Flash "wrapper" that perhaps uses an AS3 Loader class to suck in your existing SWF and receive notifications from something launched by incrontab. Flash programming is way out of scope for this answer, though it might provide a more elegant solution.
So...
Your current method consists of a launch script that first kills any existing gtk-gnash process then runs a new one. It gets relaunched from scratch when incrontab sees a change to the file. That's a viable solution if you trust that your flash application will never crash and quit, and if you always have perfect timing. One problem with it is that you've got an unknown delay between the death of one process and the start of the next. Your killall sends a signal, which gtk-gnash may respond to immediately, or after a pause. With a short pause, you might find yourself launching the SWF before the old one is fully gone. With a longer pause, you may briefly show your desktop.
A better solution might be simply to launch the SWF within a loop:
#!/bin/sh
while true; do
date '+[%Y-%m-%d %T] myfile.swf relaunched' >> /var/log/swf.log
gtk-gnash /home/my_username/path/myfile.swf
done
Then have incrontab merely kill the existing process:
/home/my_username/path/myfile.swf IN_MODIFY killall gtk-gnash
By separating the killall from the launch, you make sure that the new instance of gtk-gnash does not start until the old one has actually quit and returned control to the shell script wrapping it.
Of course, instead of using incrontab, you could alternatively install the inotify-tools package and leave a loop running:
#!/bin/sh
while inotifywait -e modify /home/my_username/path/myfile.swf; do
killall gtk-gnash
done
Same syscalls, same effect, different front-end.
If you want to be über-careful about what process you're killing, you can also store the pid of gtk-gnash in a temporary file. Here's another take on the flash player wrapper:
#!/bin/sh
while true; do
date '+[%Y-%m-%d %T] myfile.swf relaunched' >> /var/log/swf.log
gtk-gnash /home/my_username/path/myfile.swf &
echo $! > /var/run/gtk-gnash.pid
wait
done
And the incrontab line:
/home/my_username/path/myfile.swf IN_MODIFY xargs kill < /var/run/gtk-gnash.pid
Another strategy you might employ to reduce the visible effect of the kill/restart, is to take a screenshot of myfile.swf while it is running with minimal or no content, then use that as the desktop wallpaper on the player. (Or equivalent. I don't know how you're set up.) I did something similar for a digital signage solution I set up a few years ago -- from time to time we needed to kill and restart a standalone player, so we made just the "frame" of the first page that shows up. When we killed the flashplayer process, the system "seemed" to reset with no content in its boxes ... and then, a second later, content would show up. (Yes, it's a hack.)
One other tip: I've always found Adobe's stand-alone Flash player ("Projector") to be more reliable and more compatible than gtk-gnash. You can find Adobe's stand-alone player at the Adobe Support Centre Download Page, which is different from their standard Flash Player download page.

bash script on cygwin - seems to get stuck between consecutive commands.

I am using a bash script to run a number of application (some repeatedly) on a Windows machine through cygwin. The script contains commands to launch those applications, line by line. Most of these applications run for many minutes and many times I have observed that the i+1 th application is not being started even after i th application is completed. In such cases, if I press enter in the cygwin console on which the bash script is running, the next application starts running. Is it because of any issue with bash on cygwin? Or is it an issue with the Windows OS itself? Have any of you observed such an issue with bash + cygwin + Windows?
Thanks.
I think I have seen this before.
Instead of
somecommand
try
somecommand </dev/null
If that doesn't work, try
cmd /c somecommand
Or experiment with other redirections, e.g.
somecommand >/dev/null
Sounds like you may have a problem with your shell script encoding; DOS (and Windows) uses CR+LF line endings, whereas Linux uses LF endings. Try saving the file as LF.
What might also be going on:
When I was running Cygwin on a school laptop, I encountered a dramatic slowing of shell scripts vs. when they were running in a native Linux environment. This was especially apparent when running a configure script from GNU Autotools.
Check your path for slow drives. (From the Cygwin FAQ):
Why is Cygwin suddenly so slow?
If suddenly every command takes a very long time, then something is probably attempting to access a network share. You may have the obsolete //c notation in your PATH or startup files. Using //c means to contact the network server c, which will slow things down tremendously if it does not exist.
You might also want to check whether you have an antivirus program running. Antivirus programs tend to scan every single executable file as it is executed; this can cause problems for even simple shell scripts that run hundreds or even thousands of individual programs before they run their course.
This mailing list post outlines what is needed to pseudo-mount the main /usr/bin directory as cygexec. I'm not sure what that does, but I found it helped.
If you're running a configure script, try the -C option.
Hope this helps!
Occasionally, I'll get this behaviour because I have accidentally deleted the 'she-bang' at the top of the script, that is, deleted the #!/bin/bash on the first line of the script.
It's even more likely for this to happen when a parent shell script calls a child script that has the she-bang missing!
Hope this helps.
A bit of a long shot, but I have seen some similar behaviour previously.
In Windows 2000, if any program running in a command prompt window had some of it's text highlighted by the cursor, it would pause the command running, and you had to press enter or clear the highlighting to get the command prompt to continue executing.
As I said, bit of a long shot, but accidental mouse clicks could be your issue...
Install cygwin with unix style line breaks and forget weird problems like that.
Try saving your script as "the-properly-line-broken-style" for your cygwin. That is, use the style you specified under installation.
Here is some relevant information:
https://stackoverflow.com/a/7048200/657703

Resources