Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 05 Nov 2010 20:16:42 -0700
From:      Devin Teske <dteske@vicor.com>
To:        Cyrille Lefevre <cyrille.lefevre-lists@laposte.net>
Cc:        freebsd-rc@freebsd.org
Subject:   Re: sysrc(8) -- a sysctl(8)-like utility for managing rc.conf(5)
Message-ID:  <1289013402.7362.282.camel@localhost.localdomain>
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> <D763F474-8F19-4C65-B23F-78C9B137A8FE@vicor.com> <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>

next in thread | previous in thread | raw e-mail | index | archive | help
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 <-




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1289013402.7362.282.camel>