Simple shell-based daemon
Forum: Programming and Scripting
Topic: Simple shell-based daemon
started by: the Missing M
Posted by the Missing M on May 11 2007,03:11
Well it's clunky, but it works. I'm probably unduly proud of it, because this is my first attempt at a `structured' sh script. Anything before that was just a simple list of commands, which could just as easily be typed into a terminal. Of course, they have saved me the trouble of typing those same lines over and over again.
My main reason for writing it was to perform a few basic actions as root, without getting hassled for a password every time. Not really an issue in DSL, at least not from the live CD.
You don't necessarily need to have the referenced apps installed, but it might come in handy for automating other things you'd like to automate, whether they require root privs or not. That's why I'm posting it here. Oh, and because I'm unduly proud of it. ;-)
Code Sample | #!/bin/sh
echo Starting r00t_l00p...
# This script adds some super-user functionality to regular # old Wendy Whitebread accounts. # # What it does is check for certain directory names in /tmp, # then acts on whatever it finds there. So other programs, and # the user, can communicate with it via `mkdir' or a launcher # button that runs a simple `mikdir /tmp/r00t/foo' command.
mkdir -p /tmp/r00t/run chmod -R 777 /tmp/r00t sleep 11 rm -rf /tmp/r00t/run # # If the `run' folder exists, this indicates that a r00t script # has just been started, and other instances should quit now. # # Avoids multiple instances piling up from one login to the next.
while : do if [ -x /tmp/r00t/run ] then echo Ending r00t_l00p. exit 0 # What did I just say?
elif [ -x /tmp/r00t/shutdown ] #### Unused, but I might need these sometime... then rm -rf /tmp/r00t/shutdown killall sleep sudo -u moi xmms -s sleep 2 shutdown -P now "Thassal, Folks!"
elif [ -x /tmp/r00t/reboot ] then rm -rf /tmp/r00t/reboot killall sleep sudo -u moi xmms -s sleep 2 shutdown -r now "Back in a bit..."
elif [ -x /tmp/r00t/hibernate ] #### But I do need this, because the standard #### `Hibernate' button never works in Xubuntu... then rm -rf /tmp/r00t/hibernate sudo -u moi xmms -s sleep 1 umount /dev/sda1
/etc/acpi/hibernate.sh # # Requires the addition of an `&' in # /etc/acpi/hibernate.sh # # Here, on the last line; # . /etc/acpi/resume.sh & # # Otherwise, the hibernate script will just sit there # and wait, long after it's finished its work, and so # will r00t_l00p; waiting for hibernate.sh to exit.
# And on resume; # sudo -u moi mount /dev/sda1 mount /dev/sda1 sleep 7 sudo -u moi xmms -p
elif [ -x /tmp/r00t/insomnia ] #### Makes `sleep'-deferred actions happen now #### In other words; `Procrastinate Later'. then rm -rf /tmp/r00t/insomnia killall sleep
elif [ -x /tmp/r00t/ftp-stat ] #### Server status then rm -rf /tmp/r00t/ftp-stat
if [ -x /tmp/r00t/ftp-on ] then xterm -title '::0N::' \ -geometry 28x3 -e 'echo && echo \ " FTP Server is ON." && echo -n \ " " && sleep 3' & # # Woohoo! GUI notification dialogs # from a shell script!
elif [ -x /tmp/r00t/ftp-off ] then xterm -title '::0FF::' \ -geometry 28x3 -e 'echo && echo \ " FTP Server is OFF." && echo -n \ " " && sleep 3' &
# " [press any key to " && echo -n \ # " close window] " && read -n 1' &
fi
elif [ -x /tmp/r00t/ftp-switch ] #### Turn the server on or off then rm -rf /tmp/r00t/ftp-switch
if [ -x /tmp/r00t/ftp-on ] #### If it's on, stop it then xterm -title '::0FF::' \ -geometry 28x3 -e 'echo && echo \ " Stopping FTP Server." && echo -n \ " " && sleep 3' &
mv /tmp/r00t/ftp-on /tmp/r00t/ftp-off
/etc/init.d/proftpd stop /etc/init.d/proftpd force-stop sleep 3 killall -s 9 proftpd
elif [ -x /tmp/r00t/ftp-off ] #### If it's off, start it then xterm -title '::0N::' \ -geometry 28x3 -e 'echo && echo \ " Starting FTP Server." && echo -n \ " " && sleep 3' &
mv /tmp/r00t/ftp-off /tmp/r00t/ftp-on
/etc/init.d/proftpd start
elif [ -x /tmp/r00t ] #### And if you don't know, stop it anyway then mkdir -p /tmp/r00t/ftp-off
/etc/init.d/proftpd stop /etc/init.d/proftpd force-stop sleep 3 killall -s 9 proftpd fi fi
sleep 3 done |
Probably insecure as hell, because it does rely on a world-writable directory to take instructions, but that's fine with me because the only remote file access I've got going is FTP, and even that is usually turned off [does come in handy though, for transferring files between a Mac, PC and my currently favourite Linux box]. Besides, it's all sitting behind a router.
However, since this is a laptop, I do want to be sure the FTP daemon's really, truly and completely shut down when I head out to an internet cafe or something.
Blah, foo, bar, etc [and please excuse another long post],
Patrick.
Posted by humpty on May 11 2007,06:03
Quote (the Missing M @ May 11 2007,07:11) | However, since this is a laptop, I do want to be sure the FTP daemon's really, truly and completely shut down.. |
you can do a grep on a ps to a temp file. if the file is emtpy, then it's a gonna.
Posted by the Missing M on May 11 2007,07:17
Quote (humpty @ May 10 2007,19:03) | you can do a grep on a ps to a temp file. if the file is emtpy, then it's a gonna. |
AHA! ps -e|grep proftpd > ~/foo
Thanks. :-)
And I finally figured out how to get an `if [[ $this = $that ]]' statement working properly.
Code Sample | x=`ps -e|grep proftpd` if [[ $x = "" ]]; then echo phoo; else echo $x; fi |
[just some quick tests, jotted down in the terminal]
But maybe I should rephrase my original statement; I don't want to make sure anything is properly shut down, or properly launched. I want something else to do it for me.
But now it can report, accurrately, whether the thing's running or not, instead of just counting on the daemon being properly configured, and launching when it's told to launch [always has so far, but still...]. I have enough faith in killall -s 9 not to worry about that, but in most cases [probably every case] that's really overdoing it.
Thanks again,
Patrick.
Posted by the Missing M on May 19 2007,13:13
Just a quick revision, in case anyone finds this useful. When I first wrote it, I thought the `-x' test was short for `exists' btw... Kind of lucked out though, because directories also tend to be executable.
And thanks again to Humpty, for the note on ps -e | grep [foo] .
Code Sample | #!/bin/sh
echo Starting r00t_l00p...
# This script adds some super-user functionality to regular # old Wendy Whitebread accounts. # # What it does is check for certain directory names in /tmp, # then acts on whatever it finds there. So other programs, and # the user, can communicate with it via `mkdir' or a launcher # button that runs a simple `mkdir /tmp/r00t/foo' command.
mkdir -p /tmp/r00t/run chmod -R 777 /tmp/r00t sleep 11 rm -rf /tmp/r00t/run # # If the `run' folder exists, this indicates that a r00t script # has just been started, and other instances should quit now. # # Avoids multiple instances piling up from one login to the next.
while : do sleep 2 if [ -d /tmp/r00t/run ] then echo Ending r00t_l00p. exit 0 # What did I just say?
elif [ -d /tmp/r00t/shutdown ] #### Unused, but I might need these sometime... then rm -rf /tmp/r00t/shutdown killall sleep sudo -u moi xmms -s sleep 2 shutdown -P now "Thassal, Folks!"
elif [ -d /tmp/r00t/reboot ] then rm -rf /tmp/r00t/reboot killall sleep sudo -u moi xmms -s sleep 2 shutdown -r now "Back in a bit..."
elif [ -d /tmp/r00t/hibernate ] #### But I do need this, because the standard #### `Hibernate' button never works in Xubuntu... then rm -rf /tmp/r00t/hibernate sudo -u moi xmms -s sleep 1 umount /dev/sda1
/etc/acpi/hibernate.sh # # Requires the addition of an `&' in # /etc/acpi/hibernate.sh # # Here, on the last line; # . /etc/acpi/resume.sh & # # Otherwise, the hibernate script will just sit there # and wait, long after it's finished its work. And so # will r00t_l00p; waiting for hibernate.sh to exit.
# And on resume; # sudo -u moi mount /dev/sda1 mount /dev/sda1 sleep 7 sudo -u moi xmms -p
elif [ -d /tmp/r00t/insomnia ] #### Makes `sleep'-deferred actions happen now then rm -rf /tmp/r00t/insomnia killall sleep
elif [ -d /tmp/r00t/ppp-switch ] then rm -rf /tmp/r00t/ppp-switch
if [ "`ps -e | grep pppd`" = "" ] then pon Primus.ca else poff -a fi
elif [ -d /tmp/r00t/ftp-stat ] #### Server status then rm -rf /tmp/r00t/ftp-stat
if [ "`ps -e | grep proftpd`" = "" ] then xterm -title '::0FF::' \ -geometry 28x3 -e 'echo; echo \ " FTP Server is OFF." ; echo -n \ " " ; sleep 2' & # # Woohoo! GUI notification # dialogs from the shell!
else xterm -title '::0N::' \ -geometry 28x3 -e 'echo; echo \ " FTP Server is ON." ; echo -n \ " " ; sleep 2' &
# " [press any key to " ; echo -n \ # " close window] " ; read -n 1' &
fi
elif [ -d /tmp/r00t/ftp-switch ] #### Turn the server on or off then rm -rf /tmp/r00t/ftp-switch
if [ "`ps -e | grep proftpd`" = "" ] #### If it's off, start it then xterm -title '::0N::' \ -geometry 28x3 -e 'echo; echo \ " Starting FTP Server." ; echo -n \ " " ; sleep 3' &
/etc/init.d/proftpd start sleep 2 if [ "`ps -e | grep proftpd`" = "" ] then xterm -title '::FA1L::' \ -geometry 28x6 -e 'echo; echo \ " Server would not start."; echo; echo \ " [press any key" ; echo \ " to proceed]" ; echo -n \ " "; read -n 1'
sh -c 'cd /etc/init.d; \ xfce4-terminal -T "F1X PR0FTPD"' & fi
else #### If it's on, stop it
xterm -title '::0FF::' \ -geometry 28x3 -e 'echo; echo \ " Stopping FTP Server." ; echo -n \ " " ; sleep 3' &
/etc/init.d/proftpd stop sleep 1 if [ "`ps -e | grep proftpd`" = "" ] then xterm -title '::0FF::' \ -geometry 28x3 -e 'echo; echo \ " Stopped FTP Server." ; echo -n \ " " ; sleep 3' & else /etc/init.d/proftpd force-stop sleep 1 if [ "`ps -e | grep proftpd`" = "" ] then xterm -title '::0FF::' \ -geometry 28x3 -e 'echo; echo \ " Stopped FTP Server." ; echo -n \ " " ; sleep 3' & else killall -s 9 proftpd sleep 1 if [ "`ps -e | grep proftpd`" = "" ] then xterm -title '::0FF::' \ -geometry 28x3 -e 'echo; echo \ " Stopped FTP Server." ; echo -n \ " " ; sleep 3' & else xterm -title '::FA1L::' \ -geometry 28x6 -e 'echo; echo \ " WTF? Unkillable..." ; echo; echo \ " [press any key to" ; echo \ " close window]"; echo -n \ " " ; read -n 1' & fi fi fi fi fi done |
The progresion from `stop' to `force-stop' to `killall -s 9' gets a bit convoluted, but as far as I know it's never progressed past the basic `stop'. Well, not in normal use anyway. I did launch GProFTPD [a graphical configuration tool for the daemon] to test it.
BTW, does anyone know how to make grep match only whole words, and ignore word fragments like the `proftpd' in `gproftpd'? I've messed with some of its command-line options, but haven't guesed right yet.
Thanks,
Patrick.
Posted by mikshaw on May 19 2007,13:41
Quote | BTW, does anyone know how to make grep match only whole words, and ignore word fragments like the `proftpd' in `gproftpd'? |
Try using spaces within quotes or after backshlashes: grep " gproftpd " or grep \ gproftpd\ (<< a space)
Posted by ^thehatsrule^ on May 20 2007,03:02
I think he wants to _ignore_ gproftpd. Using something like this might work: grep -e " proftpd$"
Or you could use awk ... much easier to deal with fields.
Posted by the Missing M on May 20 2007,15:48
Quote (mikshaw @ May 19 2007,02:41) | Try using spaces within quotes or after backshlashes: grep " gproftpd " or grep \ gproftpd\ (<< a space) |
Thanks. :-)
But I think in this case it would fail on the *trailing* space, because ps tends to put the command name at the end of the line.
Patrick.
Posted by mikshaw on May 20 2007,15:53
I didn't notice that part. So as ^thehatsrule^ said, use $ as the last part of the grep (with the -e option for expression)
Posted by the Missing M on May 20 2007,16:00
Quote (^thehatsrule^ @ May 19 2007,16:02) | I think he wants to _ignore_ gproftpd. Using something like this might work: grep -e " proftpd$" |
Ah. And does the trailing `$' mean end of input?
Quote | Or you could use awk ... much easier to deal with fields. |
Looks good, but from a quick skim through man [m]awk, it also looks like a bit more than I'm ready for. Then again, it probably lists a lot of features I'd rarely use.
The FS / field separator thing kind of reminds me of the `text item delimiters' variable in AppleScript though. Would come in handy, as soon as I figure out how to use it. ;-)
Thanks,
Patrick.
Posted by the Missing M on May 20 2007,16:03
Quote (mikshaw @ May 20 2007,04:53) | I didn't notice that part. So as ^thehatsrule^ said, use $ as the last part of the grep (with the -e option for expression) |
Umm... Yeah I guess that is what it means.
Thanks again,
Patrick.
Posted by ^thehatsrule^ on May 20 2007,17:52
Well field separators are even in posix shells by standard...
You can look up "anchors" in regexp. Also, I think gnu's grep uses -e if needed automatically, but better keep to the standard (or use egrep.. which has slight differences)
Posted by mikshaw on May 20 2007,20:05
Quote | does the trailing `$' mean end of input? |
I think it technically means "end of line" when talking about regular expressions in general, but i think in the case of grep, end of line and end of input would be pretty much the same.
I thought for a minute that you might be able to do multiple lines with " grep end_of_first_line$beginning_of_next_line" (or something similar), but it seems to present unexpected results.
Posted by humpty on May 21 2007,15:40
for some reason the end-of-string anchor '$' doesn't work (v2.1b at least).
you can use the word boundary anchor '\b' instead
i.e ps | grep "proftpd\b"
[Edit] oops,
or rather; ps | grep "\bproftpd\b" for the whole word.
[/Edit]
Posted by ^thehatsrule^ on May 21 2007,17:35
humpty, that's probably a busybox bug... since that was updated in newer 3.x versions.
Posted by the Missing M on May 27 2007,11:39
Thanks, they both work. :-)
It also issues a warning, before running the FTP server *and* PPP at the same time, now that my *nix-box can dial out directly [don't know if anyone noticed the addition of a `pon/poff' thing in there, but it's not hiding behind a router anymore].
Cheers,
Patrick.
|