From owner-freebsd-rc@FreeBSD.ORG Sat Nov 6 03:16:46 2010 Return-Path: Delivered-To: freebsd-rc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 93AE1106564A for ; Sat, 6 Nov 2010 03:16:46 +0000 (UTC) (envelope-from dteske@vicor.com) Received: from postoffice.vicor.com (postoffice.vicor.com [69.26.56.53]) by mx1.freebsd.org (Postfix) with ESMTP id 6971B8FC15 for ; Sat, 6 Nov 2010 03:16:46 +0000 (UTC) Received: from [208.206.78.30] (port=55493 helo=dt.vicor.com) by postoffice.vicor.com with esmtpsa (SSLv3:RC4-MD5:128) (Exim 4.71) (envelope-from ) id 1PEZGl-0000A0-6M; Fri, 05 Nov 2010 20:16:45 -0700 From: Devin Teske To: Cyrille Lefevre In-Reply-To: <4CD4B040.1000804@laposte.net> References: <1286925182.32724.18.camel@localhost.localdomain> <1286996709.32724.60.camel@localhost.localdomain> <1287448781.5713.3.camel@localhost.localdomain> <1287510629.25599.2.camel@localhost.localdomain> <1288746388.7362.4.camel@localhost.localdomain> <17B64023-A64A-40DA-9CBC-A601710AB5BB@vicor.com> <1288919368.7362.35.camel@localhost.localdomain> <4CD3731C.6020501@laposte.net> <1288978858.7362.154.camel@localhost.localdomain> <4CD4B040.1000804@laposte.net> Content-Type: text/plain; charset=utf-8 Organization: Vicor, Inc Date: Fri, 05 Nov 2010 20:16:42 -0700 Message-Id: <1289013402.7362.282.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.0.2 (2.0.2-41.el4) Content-Transfer-Encoding: quoted-printable X-Scan-Signature: 5f4c109c389c05b8bd92e2f3f8169f34 X-Scan-Host: postoffice.vicor.com Cc: freebsd-rc@freebsd.org Subject: Re: sysrc(8) -- a sysctl(8)-like utility for managing rc.conf(5) X-BeenThere: freebsd-rc@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Discussion related to /etc/rc.d design and implementation." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Nov 2010 03:16:46 -0000 On Sat, 2010-11-06 at 02:32 +0100, Cyrille Lefevre wrote: > Le 05/11/2010 18:40, Devin Teske a =C3=A9crit : > > On Fri, 2010-11-05 at 03:59 +0100, Cyrille Lefevre wrote: > >> Le 05/11/2010 02:09, Devin Teske a =C3=A9crit : >=20 ... >=20 > >> awkscript=3D' > >> # %s/\\$0/$0/;s/\\\\/\\/g > >> BEGIN { ...; regex=3D"^[[:space:]]*" varname "=3D" } > >=20 > > Won't work. > >=20 > > The point of failure here is that you've taken $varname (which is a > > positional parameter passed to the shell script function) and turned it > > into an awk variable (which is never assigned). >=20 > you're wrong, the assignment is done later in : > awk -v varname=3D"$varname" ... "$awkscript" Oops, I completely missed the "-v ..." options passed to awk at the end of your e-mail. >=20 > > So right off the bat, your awk script will fail because regex will be > > assigned a value of: > >=20 > > ^[[:space:]]*=3D >=20 > wrong too, > $ v=3D123; awk -v v=3D"$v" 'BEGIN{ r=3D"^[[:space:]]*"v"=3D"; print r; ex= it}' > ^[[:space:]]*123=3D That's actually quite nice. Very nice actually. I find myself agreeing with you now that defining the awk script as literal text and then later defining the variable-bits in the awk invocation is much more readable. > bad copy/paste, I was talking about the later one (null assignment) >=20 > # Null-assignment > else if ( t1 ~ /[[:space:]];#]/ ) > { t1 =3D t2 =3D "$bquot" } > should be > # Null-assignment > else if ( t1 ~ /[[:space:]];#]/ ) { > t1 =3D t2 =3D "$bquot" > } > to look like above syntax. Ah, I was also confused by "parentheses" -- I've always referred to those as braces (of the "curly" persuasion). ... > >> # ... | ... doesn't need a final \ when wrapped after the | > >> local awk_new_value=3D"$( echo "$new_value" | > >> awk '{ gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); print }' )" > >=20 > > Wrong. Fail. And here's why... > >=20 > > You are correct that a $( ... ) block can traverse newlines. > >=20 > > However, what $( ... ) functional performs is a sub-shell. Each line > > within the $( ... ) syntax is taken as a single-line of shell to be > > executed. > >=20 > > Therefore, by deleting the back-slash at the end of the line, you've > > turned one statement into two. >=20 > no, no, no, did you tried it ? >=20 > your syntax : > x=3D$(echo x \ > | sed s,x,y,) > echo $x >=20 > the usual syntax : > x=3D$(echo x | > sed s,x,y,) > echo $x >=20 > both should print y or the shell is buggy ? >=20 > so, as I told you, the \ isn't needed after a |. no, no, no, did YOU try it? try it in bourne-shell: $ /bin/sh -c 'x=3D$(echo x | sed s,x,y,); echo $x' y $ /bin/sh -c 'x=3D$(echo x^V^J | sed s,x,y,); echo $x' Syntax error: "|" unexpected Syntax error: Error in command substitution $ /bin/sh -c 'x=3D$(echo x \ | sed s,x,y,); echo $x' y $ cat /dev/null > myscript $ chmod +x !$ $ echo '#!/bin/sh' >> !$ $ echo 'x=3D$(echo x' >> !$ $ echo '| sed s,x,y,)' >> !$ $ echo 'echo $x' >> !$ $ cat !$ #!/bin/sh x=3D$(echo x | sed s,x,y,) echo $x $ ./!$ ./myscript: 3: Syntax error: "|" unexpected ./myscript: 2: Syntax error: Error in command substitution Now, if you want to write your scripts in bash, that's fine... but don't go around claiming that it's a deficiency of bourne-shell or that "the shell is buggy". As I'll repeat... (this time with the qualifer, "in bourne-shell"): In standard POSIX-compliant bourne-shell (that's /bin/sh -- which we all know and love), both the $(...) and `...` blocks create a sub-shell where each line is a separate command. If you leave off the trailing back-slash, the shell will execute the two lines as two separate commands. Now go try it. >=20 > >> # you missed the " here > >> new_contents=3D$( tail -r "$file" 2> /dev/null ) > >=20 > > No, I did not. And here's why... >=20 > I was talking about the ones around $file, not the ones around $() Ok, so let's talk about $file... I argue that I don't need the quotes, and here's why... $file will be equal to a positional argument within rc_conf_files as defined by /etc/defaults/rc.conf and rc_conf_files is used in the following manner within /etc/defaults/rc.conf: 1 for i in ${rc_conf_files}; do 2 case ${source_files} in 3 *:$i:*) 4 ;; 5 *) 6 sourced_files=3D"${sourced_files}:$i:" 7 if [ -r $i ]; then 8 . $i 9 fi 10 ;; 12 esac 13 done In this case, I argue that I don't need quotes around $file, because the operating system itself (as you can see above; notably lines 1, 3, 7 and 8) does not support values of rc_conf_files that contain spaces. So $file is not quoted because there's no need to. The operating system will break and your boot process will be fubar long before you have a problem with my script if you have strange values for rc_conf_files set. >=20 > >> # you may want to use printf "%s" "$new_contents" instead of echo > >> # to avoid \ sequences interpretation if any > >> new_contents=3D$( echo "$new_contents" | > >> awk -v varname=3D"$varname" -v apos=3D"'" \ > >> -v new_value=3D"$new_value" "$awkscript") >=20 > when I'll have time, I'll try my code against your code to see the > differences and if there is so many bad effects ? Make sure you use bourne-shell for your tests. No shell system-level scripts within FreeBSD use bash (and rightly so, as it's not part of the base distribution). Just mentioning this because of your foible above in claiming that backslash is not required at the end of a line within a $(...) sub-shell block (which may be true for bash, or whatever shell your using, but is patently untrue for bourne-shell). >=20 > >> also, %s|/bin/sh|$_PATH_BSHELL| && _PATH_BSHELL=3D/bin/sh >=20 > it's just an habit to hardcode path within variables and a proposal. >=20 > > Not sure where you got the bquotquot (not in my code). >=20 > in my example, the %s/quot/dquot/ statment turns bquot to bquotquot :-) Which is why I would have instead said: %s/[^b]?quot/dquot/ >=20 > > perl(1)). You cannot perform multiple '%s///' operators separated by a > > semi-colon. You would get the error "E488: Trailing characters" in vim >=20 > it was just a synthetic form of writing, no more. Well... I have to say thank you. I'm somewhat new to marrying awk(1) w/ sh(1). I do have to say that `-v key=3Dvalue' is very handy! The most important thing is that this now allows me to assign the literal awkscript to a variable outside the function, meaning that the script doesn't need to be regenerated everytime the function is called. Essentially performing a caching of sorts. This should further enhance the performance of my script -- thanks! > Regards, >=20 > Cyrille Lefevre --=20 Cheers, Devin Teske -> CONTACT INFORMATION <- Business Solutions Consultant II FIS - fisglobal.com 510-735-5650 Mobile 510-621-2038 Office 510-621-2020 Office Fax 909-477-4578 Home/Fax devin.teske@fisglobal.com -> LEGAL DISCLAIMER <- This message contains confidential and proprietary information of the sender, and is intended only for the person(s) to whom it is addressed. Any use, distribution, copying or disclosure by any other person is strictly prohibited. If you have received this message in error, please notify the e-mail sender immediately, and delete the original message without making a copy. -> FUN STUFF <- -----BEGIN GEEK CODE BLOCK----- Version 3.1 GAT/CS d(+) s: a- C++(++++) UB++++$ P++(++++) L++(++++) !E--- W++ N? o? K- = w O M+ V- PS+ PE Y+ PGP- t(+) 5? X+(++) R>++ tv(+) b+(++) DI+(++) D(+) G+>++ e>= + h r>++ y+=20 ------END GEEK CODE BLOCK------ http://www.geekcode.com/ -> END TRANSMISSION <-