I'm sure I have typos below. I hope the text survived the paste process. Please forgive. I've already spent more time than I have to spare on this this eve.
Greatly improved David. Looks professional now. Here are some problems that I still see... 1: Preserving argument grouping and whitespace $@ without quotes will not preseve user-specified arguments. Here's an example. "echargs" is just a program of mine that uses parentheses to clearly show the argument groupings. Here's my test script: #!/bin/sh echo 'Without quotes:' echargs $@ echo ' With quotes:' echargs "$@" Here's a run: onella$ /tmp/passthru one ' ' 'thr ee' Without quotes: (/usr/local/bin/echargs) (one) (thr) (ee) With quotes: (/usr/local/bin/echargs) (one) ( ) (thr ee) onella$ You can see that echargs got the three arguments that the user supplied only when "$@" was used. 2: Eval The only time eval should be run is if you need to dereference something twice (like a shell variable set the the name of another shell variable). The shell automatically dereferences your command-line once. Here's another script to show how the eval dereferences and clobbers user-supplied arguments. echo 'With eval, without quotes:' eval echargs $@ echo ' With eval, with quotes:' eval echargs $@ echo ' Without eval, with quotes:' echargs "$@" Run: onella$ /tmp/thru2 one ' ' 'thr ee' With eval, without quotes: (/usr/local/bin/echargs) (one) (thr) (ee) With eval, with quotes: (/usr/local/bin/echargs) (one) (thr) (ee) Without eval, with quotes: (/usr/local/bin/echargs) (one) ( ) (thr ee) Yes, you could probably get it to work with eval by escaping (with quotes and/or backslashes), but why make the code ugly AND run a command that serves no purpose at all here (eval)? Compare the eval in runUtil.sh with the corresponding straight-forward command: eval $jdkhome/bin/java $thread_flag -classpath "\"$cp\"" \ $jargs org.hsqldb.util.$@ "$jdkhome/bin/java" $thread_flag -classpath "$cp" $jargs \ "org.hsqldb.util.$@" (I also properly quoted the last arg so it will properly preserve the user-given args as explained in the first section above. I also quoted the 0th arg to make it a little more difficult for somebody to tamper with $jdkhome in order to run another program as root). 3. Several init script problems In some environments, it can be a big problem when init scripts do not completely disassociate from the terminal. If unexpected problems come up, the bootup sequence can get stuck if the program is not disassociated from the controlling terminal (usually the console). Cron jobs can hang. Package installation scripts (like Solaris pkg and RedHat rpm) sometimes purposefully do not supply a tty at all. You aren't saving stderr. Your script does not capture any errors of the main java invocation. When you run something in the background with &, the shell return status indicates only if the process (java in this case) was successfully execed. Try this onella# ls /really/bad ls: /really/bad: No such file or directory onella# echo $? 1 onella# ls /really/bad & [1] 22994 onella# ls: /really/bad: No such file or directory [1] + Done (1) ls /really/bad onella# echo $? 0 Notice that even though "ls /really/bad" returns an error status, "ls /really/bad &" does not. I suggest that you completely disassociate the program, and then "watch" the log file to see if/when the program is successfully started. Since you can asynchronously monitor the log, you can quit as soon as the daemon is fully started. Something like startupfunc() { MAXTIME=50 # Max seconds for java to successfully start daemon age /err/log/file age /log/file java whatever <&- > /log/file 2> /err/log/file & (( ctr = 0 )) while [ $ctr -lt $MAXTIME ]; do (( ctr = ctr + 1 )) # Maybe you'd rather look for the "Listening for..." string? grep "^HSQLDB server .* is running$" /err/log/file \ > /dev/null && echo && return 0 echo -n . sleep 1 done echo Your error message return 1 } The age routine rotates the logfiles. You need a virgin error log file because you are looking for a "new" startup message. Let me know if you want my "age" script (it is currently in use on hundreds of commercial production servers). 4. Exec Wrapper scripts are an excellent place to use exec. I recommend exec "$jdkhome/bin/java" $thread_flag -classpath "$cp" \ "$jargs org.hsqldb.util.$@" for runUtil.sh. If you don't use exec, you 1: Have a bash shell running which is entirely superfluous at this point. (It can't do anything useful from now on). 2: Have a process in between the user and the program complicating signal propagation. 3: Have a process in between the user and the program complicating debugging with tools liks ps, symbolic debuggers, lsof, fuser, etc. Let me know if you'd like to see a production script which uses any of the stuff discussed above. ------------------------------------------------------- This SF.NET email is sponsored by: AMD - Your access to the experts on Hammer Technology! Open Source & Linux Developers, register now for the AMD Developer Symposium. Code: EX8664 http://www.developwithamd.com/developerlab _______________________________________________ hsqldb-developers mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/hsqldb-developers