On 09/16/13 20:48, Craig R. Skinner wrote:
On 2013-09-16 Mon 15:12 PM |, Paul de Weerd wrote:
Hi Craig,
--- cat bad_script.sh ------------------------------------------------
# This is a VERY BAD example of a script! This will break your
# shebang thingambob
echo Now what...
----------------------------------------------------------------------
I think you'd be better of making sure the first two characters in the
file are actually "#!":
head -n1 ${FILE} | grep '^#!' | sed 's/^#![[:blank:]]*//'
Good idea Paul.
Implemented below, along with rudimentary testing for a valid
interpreter:
Index: rc.subr
===================================================================
RCS file: /cvs/src/etc/rc.d/rc.subr,v
retrieving revision 1.70
diff -u -r1.70 rc.subr
--- rc.subr 11 Jul 2013 09:34:33 -0000 1.70
+++ rc.subr 16 Sep 2013 18:19:14 -0000
@@ -221,4 +221,15 @@
unset _rcflags _rcuser
pexp="${daemon}${daemon_flags:+ ${daemon_flags}}"
+file ${daemon} | fgrep -q script &&
+{
+ shebang=$(head -n 1 ${daemon} | grep '^#!' | sed 's/^#![[:blank:]]*//')
+ interpreter=$(echo ${shebang} | cut -d' ' -f1)
sed can do it all. Really. Notes:
- I separate re_quote() cause I think it can be useful in other places.
- I think re_quote() is (basic) regex complete.
- I don't care if the interpreter is (or seems) nonexistant, as that
shouldn't be a runtime error.
- I'm sure sed may die horribly if you try to feed it a 9GB oneline
file. However, if so, it should not produce any output anyway. ;)
If this would ever be considered a real problem, dd(1) would help
(as espie already mentioned).
re_quote() { sed 's/\([]^$*.\\[]\)/\\\1/g'; }
interpreter=$(
sed -n 's/^#![[:space:]]*\(.*\)/\1 /p;q' "${daemon}" |
re_quote)
pexp="$interpreter$pexp"
Moreover,
- you probably want to unset $interpreter when done.
- we might want to re_quote the entire $pexp later instead.
/Alexander
+ if [[ -f ${interpreter} && -x ${interpreter} ]]
+ then
+ pexp="${shebang} ${pexp}"
+ else
+ rc_err "$0: invalid interpreter: ${interpreter}"
+ fi
+}
rcexec="su -l -c ${daemon_class} -s /bin/sh ${daemon_user} -c"
Test scripts:
#-=-= /etc/rc.d/rcshebangtester -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#!/bin/sh
#daemon="/home/me/bin/rcshebangtester.dud"
#daemon="/home/me/bin/rcshebangtester.ksh"
daemon="/home/me/bin/rcshebangtester.pl"
. /etc/rc.d/rc.subr
rc_bg=YES
#pexp="/bin/ksh ${daemon}"
#pexp="/usr/bin/perl -T ${daemon}"
#pexp="/usr/bin/perl ${daemon}"
rc_cmd $1
#-=-= /home/me/bin/rcshebangtester.dud -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#!/var/empty
#! /dev/null
#! /usr/lib/libc.a
# swap about above
echo 'Busted!'
#-=-= /home/me/bin/rcshebangtester.ksh =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#! /bin/ksh -x
#! /bin/ksh
# swap about above
while true
do
uptime
sleep 1
done
#-=-= /home/me/bin/rcshebangtester.pl =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#! /usr/bin/perl -T
#!/usr/bin/perl
# swap about above
use strict;
use warnings;
for(;;)
{
print time(), "\n";
sleep 1;
}
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
$ sudo /etc/rc.d/rcshebangtester -d -f start; \
cat /var/run/rc.d/rcshebangtester; echo; sleep 5; \
sudo /etc/rc.d/rcshebangtester -d -f stop
doing rc_read_runfile
doing rc_check
rcshebangtester
doing rc_start
1379357218
1379357219
doing rc_wait start
doing rc_check
doing rc_write_runfile
(ok)
/usr/bin/perl -T /home/me/bin/rcshebangtester.pl
1379357220
1379357221
1379357222
1379357223
1379357224
doing rc_read_runfile
doing rc_check
rcshebangtester
doing rc_stop
doing rc_wait stop
doing rc_check
doing rc_rm_runfile
(ok)
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Any other thoughts?