Date: Thu, 20 Jun 2013 16:18:45 +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: <13CA24D6AB415D428143D44749F57D7201F98F02@ltcfiswmsgmb21> In-Reply-To: <13CA24D6AB415D428143D44749F57D7201F98E98@ltcfiswmsgmb21> References: <CAPJF9wm%2BeW-Ch99E6CZrGPcFt7hepn8y_m3fvLWTFp8PFXEt7Q@mail.gmail.com> <13CA24D6AB415D428143D44749F57D7201F98E32@ltcfiswmsgmb21> <13CA24D6AB415D428143D44749F57D7201F98E98@ltcfiswmsgmb21>
next in thread | previous in thread | raw e-mail | index | archive | help
On Jun 20, 2013, at 9:11 AM, Teske, Devin wrote: >=20 > On Jun 20, 2013, at 9:04 AM, Teske, Devin wrote: >=20 >>=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-stand= ing >>> port jboss5: >>>=20 >>> http://svnweb.freebsd.org/ports/head/java/jboss5/files/jboss5.in?revisi= on=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 th= e 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 = arguments are: >>=20 >> echo "a1" >> foofile >>=20 >> And thus, eval does what it does best=85 evaluates the expressions as a = set of shell statements. >>=20 >> NOTE: The rc script probably assumed bash and was ported from another sy= stem 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 c= onditional 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 directo= ry" >>=20 >> =3D=3D=3D >>=20 >=20 > Yeah=85 don't do that=85 the moment I hit send, it dawned on me that the = extra file-descriptor (however cute), is entire unnecessary=85 >=20 > =3D=3D=3D >=20 > #!/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 >=20 > =3D=3D=3D >=20 >=20 >=20 >> So rather than having to prefix "eval" to every command *and* escape all= the quotes and expansions=85 the above instead changes from (old) attempti= ng to use a conditional redirect syntax (by way of $logging variable) to (n= ew/above) having every command redirect stdout/stderr but having the destin= ations 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 "#!/u= sr/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" o= r ">&3 2>&4" (the leading 1 on ">&" in the first option is actually the imp= lied default, so you can omit it and go for the second option if you like; = however since you can't say "exec 3>&" and have to say "exec 3>&1", I tend = to think the first option is more explicitly-clear in what's going on with = the file-descriptors). >>=20 >=20 > Actually=85 you could potentially fix this with one line of code=85 >=20 > [ "$logging" ] && exec 1>>/tmp/log.stdout 2>>/tmp/log.stderr >=20 > And then go remove the "$logging" from the end of each line. Even better than removing "$logging" (or $log_args) from the end of each li= ne=85 Just set it to NULL. So in the case of your earlier example=85 >>> %%APP_SHORTNAME%%_logging=3D"${%%APP_SHORTNAME%%_logging:-">> >>> ${%%APP_SHORTNAME%%_logdir}/stdout.log 2>> >>> ${%%APP_SHORTNAME%%_logdir}/stderr.log"}" I would do the following=85 # # Do the real task of enabling debug output # if [ "${%%APP_SHORTNAME%%_logging}" ]; then exec 1>>"${%%APP_SHORTNAME%%_logdir}/stdout.log" exec 2>>"${%%APP_SHORTNAME%%_logdir}/stderr.log" fi # # Dirty hack to make it so I don't have to # remove ${%%APP_SHORTNAME%%_logging} # from each line. # %%APP_SHORTNAME%%_logging=3D > --=20 > Devin >=20 > _____________ > The information contained in this message is proprietary and/or confident= ial. If you are not the intended recipient, please: (i) delete the message = and all copies; (ii) do not disclose, distribute or use the message in any = manner; and (iii) notify the sender immediately. In addition, please be awa= re that any message addressed to our domain is subject to archiving and rev= iew by persons other than the intended recipient. Thank you. _____________ 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?13CA24D6AB415D428143D44749F57D7201F98F02>