make a program reload an already opened file on file change - bash

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.

Related

Why does Fastscripts work with this but Platypus doesn't

Mac running Catalina. This code
#!/bin/bash
pbpaste|pbcopy
pbpaste>/tmp/tmp$$
open -W -a macvim /tmp/tmp$$
while [ `ps -A|grep MacVim|wc -l` -gt 1 ]
do sleep 1
done
cat /tmp/tmp$$|pbcopy
rm -f /tmp/tmp$$
is intended to plain-text the paste buffer then call up a terminal running macvim so I can use vi with less faff then put the result back in the clipboard. Its a way to speed-up editing when using various tools other tools and I just want to edit a section with vi.
I works well when called from Fastscripts or just plain execution but it won't work when I use Platypus to build a menubar app so its one fast click to use it - or rather, it works sometimes. Sometimes it hangs because it cannot connect input to the window in which macvim runs. I have to kill it from Activity Monitor to regain any control of input to other windows such as terminal. I've tried connecting stdin in the "open" command but still only works sometimes. And it shouldn't be standin anyway.
How is Fastscripts launching it and how can I do the same inside the script ?
I'd like very much to be able to launch it with a single click from the menubar but I don't know how to. I can build the platypus app if I know what to put in the shell script.
Thanks
andy

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!

How can I tell my bash prompt to indicate whether there's a backgrounded emacsclient session exists

I'm using, OS X, and mainly terminal and emacsclient.
When I do shell stuff, I background my emacsclient with Control-Z
Someties I forget whether i've done that, and end up spawning additional emacsclient sessions, which I don;t want to do.
It would be cool if the bash prompt can tell me whether emacsclient jobs up in the jobs output
Minimal example for bash, using sleep instead of emacsclient.
PS1="\`if jobs | grep -q sleep; then echo 'sleep jobs' ; else echo 'no sleep jobs' ; fi\`\\\$ "
You might want to filter on stopped jobs (jobs -s).
You can get fancier by echoing escape sequences instead of just strings to colorize it.
While I think #jpkota provides a workable answer, I wonder if maybe your worrying too much. Provided emacsclient is working OK, there is no problem with having multiple emacsclient sessions running at once - in fact, it is sort of designed to do that. The emacsclient connections are light-weight and if there is a chance you might need to use the same file/buffer again, you may as well keep them around and just open new ones when needed and get rid of the ones you don't think you will need. The whole benefit of emacscleint is that opening new windows/buffers is really fast and if you use the GUI verison, they just pop up in their own window.
There is also a package in elpa which may be useful called osx-pseudo-daemon, which addresses a problem that can occur if you close all emacsclient windows which prevents the main emacs from responding (this is when yu run emacs from launchctl.
What I tend to do is run emacsclient in GUI mode rather than inside a terminal. When I run emacsclient I put it in the background so that it doesn't block my terminal and use the -c flag.(I actually have a shell script which makes this easy - see http://emacsformacosx.com/tips for some ideas. I leave the emacsclient window open and just switch to it if I need to do some emacs editing etc.

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

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.

SSH, entered command but it didn't execute, can't type anything

I used the command tar -x file.tar.gz and, for one reason or anything it failed. Then I get stuck being able to type anything in, but not being able to run any more commands. Pressing enter just gives me a new line. I don't know how to break out of it either (escape etc doesn't work). The only way I can get back working is to close putty and reconnect.
Is there a way to get it back to normal so I can keep going because it's irritating closing it all the time.
Try hitting CTRL+C :) This will cancel/kill/stop the running command!
But the best way to untar is to use -v to verbose the output :
tar -zxvf yourfile.tar.gz
With that, you'll perhaps see that your file just take more time than you thought unarchiving ;)
Ctrl-C can be used to send a break to the executable that's hanging, but it's up to the application to handle it. Ctrl-Z will break you out of the running executable, but you'll need to then manually kill the process.
What you're doing wrong is you're not gunzipping the archive.
Try this
tar -zxf file.tar.gz
If you want to quit it, press CTRL+c.
If you want to keep it but being able to write more commands while it's working, press CTRL+z and bg.
Then it will work in the background.
Your command failed because it is trying to read stdin. This is because you never told it the name of the tar file with an "f" option.
A good Idea would be to use GNU screen. That way, when a command hangs, you can open another screen and take a look at the system (e.g. top to see if tar is still working) or you could kill the process by pressing (strg+a) + k to hard-kill the running process within the screen-session.
Screen also has the nice feature that your processes keep running even though your SSH-connection died. It's a lifesaver!
Your tar invocation is waiting for input on the command line as the others pointed out. You may also use Ctrl-D to indicate EOF to the tar process.

Resources