Date: Thu, 20 Jun 2013 16:11:39 +0000 From: "Teske, Devin" <Devin.Teske@fisglobal.com> To: Alexander Yerenkow <yerenkow@gmail.com> Cc: FreeBSD Hackers <freebsd-hackers@freebsd.org>, Devin Teske <dteske@freebsd.org> Subject: Re: Shell variables containing output redirects Message-ID: <13CA24D6AB415D428143D44749F57D7201F98E98@ltcfiswmsgmb21> In-Reply-To: <13CA24D6AB415D428143D44749F57D7201F98E32@ltcfiswmsgmb21> References: <CAPJF9wm%2BeW-Ch99E6CZrGPcFt7hepn8y_m3fvLWTFp8PFXEt7Q@mail.gmail.com> <13CA24D6AB415D428143D44749F57D7201F98E32@ltcfiswmsgmb21>
next in thread | previous in thread | raw e-mail | index | archive | help
On Jun 20, 2013, at 9:04 AM, Teske, Devin wrote: >=20 > On Jun 20, 2013, at 7:57 AM, Alexander Yerenkow wrote: >=20 >> Hello all! >>=20 >> I have a problem with port JBoss72, which tries to behave as long-standi= ng >> port jboss5: >>=20 >> http://svnweb.freebsd.org/ports/head/java/jboss5/files/jboss5.in?revisio= n=3D302141&view=3Dmarkup >>=20 >>=20 >>=20 >> In rc run script there is such line: >>=20 >> %%APP_SHORTNAME%%_logging=3D"${%%APP_SHORTNAME%%_logging:-">> >> ${%%APP_SHORTNAME%%_logdir}/stdout.log 2>> >> ${%%APP_SHORTNAME%%_logdir}/stderr.log"}" >>=20 >> Which provides way to overwrite default log location in /etc/rc.conf. >>=20 >> But this not working at all, all these redirects treated as simple >> parameters for run script. >>=20 >> I made small test, to show my problem: >>=20 >> #!/bin/sh >>=20 >> logfile=3D"supposed-to-be.log" >> log=3D">> ${logfile}" >> echo "a1" >> ${logfile} >> echo "a2" ${log} >> cmd=3D"echo \"a3\" ${log}" >> echo $cmd >> $cmd >> more ${logfile} >>=20 >> Here's execution output: >>=20 >> # ./t1.sh >> a2 >> supposed-to-be.log >> echo "a3" >> supposed-to-be.log >> "a3" >> supposed-to-be.log >> a1 >>=20 >> 1. My question is - Which are correct way to specify such redirects to be >> overridden? >>=20 >=20 > If you must have a conditional redirect in the above manner (in which the= redirect syntax is part of a variable): >=20 > to_foofile=3D">> foofile" > eval echo \"a1\" $to_foofile >=20 > The shell will do a first-pass on the arguments, so what "eval" sees as a= rguments are: >=20 > echo "a1" >> foofile >=20 > And thus, eval does what it does best=85 evaluates the expressions as a s= et of shell statements. >=20 > NOTE: The rc script probably assumed bash and was ported from another sys= tem where /bin/sh was indeed bash (but in FreeBSD, /bin/sh is not bash and = is much more strict in adhering to POSIX standards). >=20 > However, I can't in all earnest recommend that approach as a method of co= nditional logging when there are so many better solutions. >=20 > Here's one of my favorites for quick-and-dirty conditional logging: >=20 > =3D=3D=3D >=20 > #!/bin/sh >=20 > if : some condition to enable debugging; then > exec 3>>/tmp/log.stdout 4>>/tmp/log.stderr > else > exec 3>&1 4>&2 > fi >=20 > echo "a1" 1>&3 2>&4 > # "a1" ends up in /tmp/log.stdout >=20 > ls /nosuchfile 1>&3 2>&4 > # You get in /tmp/log.stderr: "ls: /nosuchfile: No such file or director= y" >=20 > =3D=3D=3D >=20 Yeah=85 don't do that=85 the moment I hit send, it dawned on me that the ex= tra file-descriptor (however cute), is entire unnecessary=85 =3D=3D=3D #!/bin/sh if : some condition to enable debugging; then exec 1>>/tmp/log.stdout 2>>/tmp/log.stderr fi echo d1 # if debugging, goes to /tmp/log.stdout # if no debugging, goes to console ls /nosuchfile # if debugging, an error goes to /tmp/log.stderr # if no debugging, error goes to console =3D=3D=3D > So rather than having to prefix "eval" to every command *and* escape all = the quotes and expansions=85 the above instead changes from (old) attemptin= g to use a conditional redirect syntax (by way of $logging variable) to (ne= w/above) having every command redirect stdout/stderr but having the destina= tions of the redirect change based on some pre-condition. >=20 >=20 >=20 >> 2. tomcat6.in, rubyrep.in, tclhttpd.in, geoserver.in, and many more rc >> scripts from ports are using something like this: >>=20 >> log_args=3D">> ${tclhttpd_stdout_log} 2>> ${tclhttpd_stderr_log} " >>=20 >> and after that use $log_args. >>=20 >> Are they silently broken, or am I missing something? >>=20 >=20 > I would call that broken if the invocation line at the top of the script = is #!/bin/sh (it may not be broken if you instead see something like "#!/us= r/bin/env bash"). >=20 >=20 >=20 >=20 >> 3. Should I build up $cmd, and run >> eval "$cmd" - would this be nice ro dirty hack? >>=20 >=20 > Nah=85 just go through and replace "$log_args" with either "1>&3 2>&4" or= ">&3 2>&4" (the leading 1 on ">&" in the first option is actually the impl= ied default, so you can omit it and go for the second option if you like; h= owever since you can't say "exec 3>&" and have to say "exec 3>&1", I tend t= o think the first option is more explicitly-clear in what's going on with t= he file-descriptors). >=20 Actually=85 you could potentially fix this with one line of code=85 [ "$logging" ] && exec 1>>/tmp/log.stdout 2>>/tmp/log.stderr And then go remove the "$logging" from the end of each line. --=20 Devin _____________ The information contained in this message is proprietary and/or confidentia= l. If you are not the intended recipient, please: (i) delete the message an= d all copies; (ii) do not disclose, distribute or use the message in any ma= nner; and (iii) notify the sender immediately. In addition, please be aware= that any message addressed to our domain is subject to archiving and revie= w by persons other than the intended recipient. Thank you.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?13CA24D6AB415D428143D44749F57D7201F98E98>