From owner-freebsd-rc@FreeBSD.ORG Mon Nov 1 11:07:04 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 A9B2B10656B1 for ; Mon, 1 Nov 2010 11:07:04 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 8C2EE8FC21 for ; Mon, 1 Nov 2010 11:07:04 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id oA1B749t019277 for ; Mon, 1 Nov 2010 11:07:04 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id oA1B73vU019275 for freebsd-rc@FreeBSD.org; Mon, 1 Nov 2010 11:07:03 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 1 Nov 2010 11:07:03 GMT Message-Id: <201011011107.oA1B73vU019275@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: gnats set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-rc@FreeBSD.org Cc: Subject: Current problem reports assigned to freebsd-rc@FreeBSD.org 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: Mon, 01 Nov 2010 11:07:04 -0000 Note: to view an individual PR, use: http://www.freebsd.org/cgi/query-pr.cgi?pr=(number). The following is a listing of current problems submitted by FreeBSD users. These represent problem reports covering all versions including experimental development code and obsolete releases. S Tracker Resp. Description -------------------------------------------------------------------------------- o conf/151063 rc [rc.subr] Verify network link and packet flow before s o conf/150752 rc [rc.subr] [patch] be not needed to eval $_pidcmd on re o conf/150474 rc [patch] rc.d/accounting: Add ability to set location o o conf/149867 rc [PATCH] rc.d script to manage multiple FIBS (kern opti o conf/149831 rc [PATCH] add support to /etc/rc.d/jail for delegating Z o conf/148961 rc [PATCH] netstart and network_ipv6 contains references o conf/148656 rc rc.firewall(8): {oip} and {iip} variables in rc.firewa o conf/147685 rc [rc.d] [patch] new feature for /etc/rc.d/fsck o conf/147444 rc [rc.d] [patch] /etc/rc.d/zfs stop not called on reboot o conf/146053 rc [patch] [request] shutdown of jails breaks inter-jail o conf/145445 rc [rc.d] error in /etc/rc.d/jail (bad logic) o conf/145440 rc [rc.d] [patch] add multiple fib support (setfib) in /e o conf/145399 rc [patch] rc.d scripts are unable to start/stop programs o conf/145344 rc [patch] Fix kitchen sink approach for rc.d scripts ins o conf/145009 rc [patch] rc.subr(8): rc.conf should allow mac label con o conf/144213 rc [rc.d] [patch] Disappearing zvols on reboot o conf/143637 rc [patch] ntpdate(8) support for ntp-servers supplied by o conf/143085 rc [patch] ftp-proxy(8) rc(8) with multiple instances o conf/143084 rc [jail] [patch]: fix rc.d/jail creating stray softlinks o conf/142973 rc [jail] [patch] Strange counter init value in jail rc o conf/142434 rc [patch] Add cpuset(1) support to rc.subr(8) o conf/142304 rc rc.conf(5): mdconfig and mdconfig2 rc.d scripts lack e o conf/141909 rc rc.subr(8): [patch] add rc.conf.d support to /usr/loca o conf/141907 rc [rc.d] Bug if mtu (maybe others?) is set as first argu o conf/141678 rc [patch] A minor enhancement to how /etc/rc.d/jail dete o conf/141275 rc [request] dhclient(8) rc script should print something o conf/140440 rc [patch] allow local command files in rc.{suspend,resum o conf/140261 rc [patch] Improve flexibility of mdconfig2 startup scrip o conf/138208 rc [rc.d] [patch] Making rc.firewall (workstation) IPv6 a o conf/137629 rc [rc.d] background_dhclient rc.conf option causing doub o conf/137470 rc [PATCH] /etc/rc.d/mdconfig2 : prioritize cli parameter o conf/137271 rc [rc.d] Cannot update /etc/host.conf when root filesyst o conf/136875 rc [request] _flags appending o conf/136624 rc [rc.d] sysctl variables for ipnat are not applied on b o conf/135338 rc [rc.d] pf startup order seems broken [regression] o conf/134918 rc [patch] rc.subr fails to detect perl daemons o conf/134660 rc [patch] rc-script for initializing ng_netflow+ng_ipfw o conf/134333 rc PPP configuration problem in the rc.d scripts in combi o conf/134006 rc [patch] Unload console screensaver kernel modules if s o conf/133987 rc [rc.d] defaultroute broken with DHCP in some cases o conf/133890 rc [patch] sshd(8): add multiple profiles to the rc.d scr o conf/132483 rc rc.subr(8) [patch] setfib(1) support for rc.subr o conf/132476 rc [rc.d] [patch] add support setfib(1) in rc.d/routing o conf/128299 rc [patch] /etc/rc.d/geli does not mount partitions using o conf/127917 rc [patch] dumpon rejects on start with physmem>swap even o bin/126562 rc rcorder(8) fails to run unrelated startup scripts when o conf/126392 rc [patch] rc.conf ifconfig_xx keywords cannot be escaped p bin/126324 rc [patch] rc.d/tmp: Prevent mounting /tmp in second tim o conf/124747 rc [patch] savecore can't create dump from encrypted swap o conf/124248 rc [jail] [patch] add support for nice value for rc.d/jai o conf/123734 rc [patch] Chipset VIA CX700 requires extra initializatio o conf/123222 rc [patch] Add rtprio(1)/idprio(1) support to rc.subr(8). o conf/122968 rc [rc.d] /etc/rc.d/addswap: md swapfile multiplication a o conf/122477 rc [patch] /etc/rc.d/mdconfig and mdconfig2 are ignoring o conf/122170 rc [patch] [request] New feature: notify admin via page o o kern/121566 rc [nfs] [request] [patch] ethernet iface should be broug o conf/120431 rc [patch] devfs.rules are not initialized under certain o conf/120406 rc [devd] [patch] Handle newly attached pcm devices (eg. o conf/119874 rc [patch] "/etc/rc.d/pf reload" fails if there are macro o conf/119076 rc [patch] [rc.d] /etc/rc.d/netif tries to remove alias a o bin/118325 rc [patch] [request] new periodic script to test statuses o conf/118255 rc savecore never finding kernel core dumps (rcorder prob o conf/117935 rc [patch] ppp fails to start at boot because of missing o conf/113915 rc [patch] ndis wireless driver fails to associate when i o conf/109980 rc /etc/rc.d/netif restart doesn't destroy cloned_interfa o conf/109562 rc [rc.d] [patch] [request] Make rc.d/devfs usable from c o conf/108589 rc rtsol(8) fails due to default ipfw rules o conf/106009 rc [ppp] [patch] [request] Fix pppoed startup script to p o conf/105689 rc [ppp] [request] syslogd starts too late at boot o conf/105568 rc [patch] [request] Add more flexibility to rc.conf, to o conf/105145 rc [ppp] [patch] [request] add redial function to rc.d/pp o conf/104549 rc [patch] rc.d/nfsd needs special _find_processes functi o conf/102700 rc [geli] [patch] Add encrypted /tmp support to GELI/GBDE o conf/99721 rc [patch] /etc/rc.initdiskless problem copy dotfile in s o conf/99444 rc [patch] Enhancement: rc.subr could easily support star o conf/96343 rc [patch] rc.d order change to start inet6 before pf o conf/93815 rc [patch] Adds in the ability to save ipfw rules to rc.d o conf/92523 rc [patch] allow rc scripts to kill process after a timeo o conf/89870 rc [patch] [request] make netif verbose rc.conf toggle o conf/89061 rc [patch] IPv6 6to4 auto-configuration enhancement o conf/88913 rc [patch] wrapper support for rc.subr o conf/85819 rc [patch] script allowing multiuser mode in spite of fsc o kern/81006 rc ipnat not working with tunnel interfaces on startup o conf/77663 rc Suggestion: add /etc/rc.d/addnetswap after addcritremo o conf/73677 rc [patch] add support for powernow states to power_profi o conf/58939 rc [patch] dumb little hack for /etc/rc.firewall{,6} o conf/56934 rc [patch] rc.firewall rules for natd expect an interface o conf/45226 rc [patch] Fix for rc.network, ppp-user annoyance o conf/44170 rc [patch] Add ability to run multiple pppoed(8) on start 89 problems total. From owner-freebsd-rc@FreeBSD.ORG Wed Nov 3 01:06:32 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 F27A6106566C; Wed, 3 Nov 2010 01:06:32 +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 D7C678FC12; Wed, 3 Nov 2010 01:06:32 +0000 (UTC) Received: from [208.206.78.30] (port=43992 helo=dt.vicor.com) by postoffice.vicor.com with esmtpsa (SSLv3:RC4-MD5:128) (Exim 4.71) (envelope-from ) id 1PDRo4-0006Hm-Tg; Tue, 02 Nov 2010 18:06:31 -0700 From: Devin Teske To: freebsd-rc@freebsd.org In-Reply-To: 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> Content-Type: text/plain Organization: Vicor, Inc Date: Tue, 02 Nov 2010 18:06:28 -0700 Message-Id: <1288746388.7362.4.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.0.2 (2.0.2-41.el4) Content-Transfer-Encoding: 7bit X-Scan-Signature: eeda19339be77836aac052df51e20ca1 X-Scan-Host: postoffice.vicor.com Cc: Julian Elischer 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: Wed, 03 Nov 2010 01:06:33 -0000 On Wed, 2010-10-20 at 23:46 -0700, Devin Teske wrote: > On Oct 19, 2010, at 10:50 AM, Devin Teske wrote: > > > On Mon, 2010-10-18 at 17:39 -0700, Devin Teske wrote: > >> On Wed, 2010-10-13 at 12:05 -0700, Devin Teske wrote: > >>> On Tue, 2010-10-12 at 16:13 -0700, Devin Teske wrote: > >>>> Hey all, > >>>> > >>>> [...] > >>>> > >>>> Behold... sysrc(8) v2.0 > >>>> > >>>> #!/bin/sh > >>>> [...] > >>> > >>> Version 2.1 is available here: http://druidbsd.sf.net/ > >> > >> Version 2.2 now. > >> Same links. > >> > >> I added `-R dir' for specifying an alternate root (other than `/') > >> directory (mostly for handling jails). > > > > Version 2.3 now. > > Same links. > > > > Version 2.4 now. > Same links. > Version 2.5 now. Same links. That should be all the features that were requested (and some that weren't). > > > >> > >>> > >>> Direct links: > >>> http://druidbsd.sf.net/download/sysrc.gz (download gzipped) > >>> http://druidbsd.sf.net/download/sysrc.txt (view as text) > >>> > >>> Here's the changes: > >>> > >> > > --- sysrc.2_4 2010-10-20 23:36:51.000000000 -0700 +++ sysrc 2010-11-02 17:47:23.000000000 -0700 @@ -2,8 +2,8 @@ # -*- tab-width: 4 -*- ;; Emacs # vi: set tabstop=4 :: Vi/ViM # -# Revision: 2.4 -# Last Modified: October 20th, 2010 +# Revision: 2.5 +# Last Modified: November 2nd, 2010 ############################################################ COPYRIGHT # # (c)2010. Devin Teske. All Rights Reserved. @@ -30,6 +30,11 @@ # SUCH DAMAGE. # # AUTHOR DATE DESCRIPTION +# dteske 2010.11.02 Preserve leading/trailing whitespace in sysrc_set(). +# dteske 2010.11.02 Deprecate lrev() in favor of tail(1)'s `-r' flag. +# dteske 2010.11.02 Map `-R dir' to `-j jail' if `dir' maps to a single +# running jail (or produce an error if `dir' maps to +# many running jails). # dteske 2010.10.20 Make `-j jail' and `-R dir' more secure # dteske 2010.10.19 Add `-j jail' for operating on jails (see jexec(8)). # dteske 2010.10.18 Add `-R dir' for operating in different root-dir. @@ -105,6 +110,16 @@ ############################################################ FUNCTION +# have $anything +# +# A wrapper to the `type' built-in. Returns true if argument is a valid shell +# built-in, keyword, or externally-tracked binary, otherwise false. +# +have() +{ + type "$@" > /dev/null 2>&1 +} + # fprintf $fd $fmt [ $opts ... ] # # Like printf, except allows you to print to a specific file-descriptor. Useful @@ -382,50 +397,6 @@ return $FAILURE # Not found } -# ... | lrev -# lrev $file ... -# -# Reverse lines of input. Unlike rev(1) which reverses the ordering of -# characters on a single line, this function instead reverses the line -# sequencing. -# -# For example, the following input: -# -# Line 1 -# Line 2 -# Line 3 -# -# Becomes reversed in the following manner: -# -# Line 3 -# Line 2 -# Line 1 -# -lrev() -{ - local stdin_rev= - if [ $# -gt 0 ]; then - # - # Reverse lines from files passed as positional arguments. - # - while [ $# -gt 0 ]; do - local file="$1" - [ -f "$file" ] && lrev < "$file" - shift 1 - done - else - # - # Reverse lines from standard input - # - while read -r LINE; do - stdin_rev="$LINE -$stdin_rev" - done - fi - - echo -n "$stdin_rev" -} - # sysrc_set $varname $new_value # # Change a setting in the system configuration files (edits the files in-place @@ -485,19 +456,49 @@ # # Operate on the matching file, replacing only the last occurrence. # - local new_contents="`lrev $file 2> /dev/null | \ + local __IFS="$IFS" + local new_contents="`tail -r $file 2> /dev/null | \ ( found= + IFS= while read -r LINE; do - if [ ! "$found" ]; then - match="$( echo "$LINE" | grep "$regex" )" - if [ "$match" ]; then - LINE="$varname"'="'"$new_value"'"' - found=1 - fi - fi - echo "$LINE" + if [ "$found" ]; then + echo "$LINE" + continue + fi + + # + # Determine what type of assignment is being performed + # and append the proper expression to accurately replace + # the current value. + # + # NOTE: The base regular expression below should match + # functionally the regex used by sysrc_find(). + # + regex="^([[:space:]]*$varname=)" + if echo "$LINE" | grep -Eq "$regex'"; then + # found assignment w/ single-quoted value + found=1 + regex="$regex(')([^']*)('{0,1})" + elif echo "$LINE" | grep -Eq "$regex"'"'; then + # found assignment w/ double-quoted value + found=1 + regex="$regex"'(")([^\\\\]*\\\\")*[^"]*("{0,1})' + elif echo "$LINE" | grep -Eq "$regex[^[:space:]]"; then + # found assignment w/ non-quoted value + found=1 + regex="$regex()([^[:space:]]*)()" + + # Use quotes if replacing with multi-word value + [ "${new_value%[$__IFS]*}" != "$new_value" ] \ + && new_value='"'"$new_value"'"' + fi + + [ "$found" ] && LINE="$( echo "$LINE" \ + | sed -re "s/$regex/\1\2$new_value\4/" )" + + echo "$LINE" done - ) | lrev`" + ) | tail -r`" [ "$new_contents" ] || return $FAILURE @@ -668,6 +669,52 @@ exit $? elif [ "$ROOTDIR" ]; then # + # Make sure that the root directory specified is not to any + # running jails. + # + # NOTE: To maintain backward compatibility with older jails on + # older systems, we will not perform this check if either the + # jls(8) or jexec(8) utilities are missing. + # + if have jexec && have jls; then + jid="`jls jid path | \ + ( + while read JID JROOT; do + [ "$JROOT" = "$ROOTDIR" ] || continue + echo $JID + done + )`" + + # + # If multiple running jails match the specified root + # directory, exit with error. + # + if [ "$jid" -a "${jid%[$IFS]*}" != "$jid" ]; then + die "%s: %s: %s" "$progname" "$ROOTDIR" \ + "$( echo "Multiple jails claim this" \ + "directory as their root." \ + "(use \`-j jail' instead)" )" + fi + + # + # If only a single running jail matches the specified + # root directory, implicitly use `-j jail'. + # + if [ "$jid" ]; then + # + # Re-execute outselves with sh(1) via jexec(8) + # + ( echo set -- $args + cat $0 + ) | env - RC_DEFAULTS="$RC_DEFAULTS" \ + /usr/sbin/jexec "$jid" /bin/sh + exit $? + fi + + # Otherwise, fall through and allow chroot(8) + fi + + # # Re-execute ourselves with sh(1) via chroot(8) # ( echo set -- $args -- 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+ ------END GEEK CODE BLOCK------ http://www.geekcode.com/ -> END TRANSMISSION <- From owner-freebsd-rc@FreeBSD.ORG Wed Nov 3 03:48:05 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 1E77C106564A; Wed, 3 Nov 2010 03:48:05 +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 0063A8FC17; Wed, 3 Nov 2010 03:48:04 +0000 (UTC) Received: from [173.241.24.124] (port=60551 helo=[10.0.0.109]) by postoffice.vicor.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.71) (envelope-from ) id 1PDUKP-0000Ne-Oe; Tue, 02 Nov 2010 20:48:04 -0700 Mime-Version: 1.0 (Apple Message framework v1081) From: Devin Teske In-Reply-To: <1288746388.7362.4.camel@localhost.localdomain> Date: Tue, 2 Nov 2010 20:48:00 -0700 Message-Id: <17B64023-A64A-40DA-9CBC-A601710AB5BB@vicor.com> 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> To: Devin Teske X-Mailer: Apple Mail (2.1081) X-Scan-Signature: d9b0e5168295576e08739e97341a8894 X-Scan-Host: postoffice.vicor.com Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.5 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: Wed, 03 Nov 2010 03:48:05 -0000 On Nov 2, 2010, at 6:06 PM, Devin Teske wrote: > On Wed, 2010-10-20 at 23:46 -0700, Devin Teske wrote:=20 >> On Oct 19, 2010, at 10:50 AM, Devin Teske wrote: >>=20 >>> On Mon, 2010-10-18 at 17:39 -0700, Devin Teske wrote: >>>> On Wed, 2010-10-13 at 12:05 -0700, Devin Teske wrote:=20 >>>>> On Tue, 2010-10-12 at 16:13 -0700, Devin Teske wrote: >>>>>> Hey all, >>>>>>=20 >>>>>> [...] >>>>>>=20 >>>>>> Behold... sysrc(8) v2.0 >>>>>>=20 >>>>>> #!/bin/sh >>>>>> [...] >>>>>=20 >>>>> Version 2.1 is available here: http://druidbsd.sf.net/ >>>>=20 >>>> Version 2.2 now. >>>> Same links. >>>>=20 >>>> I added `-R dir' for specifying an alternate root (other than `/') >>>> directory (mostly for handling jails). >>>=20 >>> Version 2.3 now. >>> Same links. >>>=20 >>=20 >> Version 2.4 now. >> Same links. >>=20 >=20 > Version 2.5 now. > Same links. >=20 > That should be all the features that were requested (and some that > weren't). Minor fix ^_^ Version 2.5.1 now. >=20 >>>=20 >>>>=20 >>>>>=20 >>>>> Direct links: >>>>> http://druidbsd.sf.net/download/sysrc.gz (download gzipped) >>>>> http://druidbsd.sf.net/download/sysrc.txt (view as text) >>>>>=20 >>>>> Here's the changes: >>>>>=20 >>>>=20 >>>=20 >=20 >=20 --- sysrc.2_5 2010-11-02 17:56:54.000000000 -0700 +++ sysrc 2010-11-02 20:35:12.000000000 -0700 @@ -2,7 +2,7 @@ # -*- tab-width: 4 -*- ;; Emacs # vi: set tabstop=3D4 :: Vi/ViM # -# Revision: 2.5 +# Revision: 2.5.1 # Last Modified: November 2nd, 2010 ############################################################ COPYRIGHT # @@ -30,6 +30,7 @@ # SUCH DAMAGE. # # AUTHOR DATE DESCRIPTION +# dteske 2010.11.02 Fix quotes when replacing null assignment. # dteske 2010.11.02 Preserve leading/trailing whitespace in = sysrc_set(). # dteske 2010.11.02 Deprecate lrev() in favor of tail(1)'s `-r' = flag. # dteske 2010.11.02 Map `-R dir' to `-j jail' if `dir' maps to a = single @@ -461,6 +462,7 @@ ( found=3D IFS=3D while read -r LINE; do + # If already found, just spew... if [ "$found" ]; then echo "$LINE" continue @@ -491,8 +493,16 @@ # Use quotes if replacing with multi-word value [ "${new_value%[$__IFS]*}" !=3D "$new_value" ] \ && new_value=3D'"'"$new_value"'"' + elif echo "$LINE" | grep -Eq "$regex"; then + # found null-assignment + found=3D1 + regex=3D"$regex()()()" + + # Always use quotes + new_value=3D'"'"$new_value"'"' fi =20 + # Do the deed... [ "$found" ] && LINE=3D"$( echo "$LINE" \ | sed -re "s/$regex/\1\2$new_value\4/" )" =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 <- From owner-freebsd-rc@FreeBSD.ORG Fri Nov 5 01:09:33 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 E5AC81065674; Fri, 5 Nov 2010 01:09:33 +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 C9CEC8FC2E; Fri, 5 Nov 2010 01:09:33 +0000 (UTC) Received: from [208.206.78.30] (port=50454 helo=dt.vicor.com) by postoffice.vicor.com with esmtpsa (SSLv3:RC4-MD5:128) (Exim 4.71) (envelope-from ) id 1PEAo5-0006tZ-5P; Thu, 04 Nov 2010 18:09:32 -0700 From: Devin Teske To: freebsd-rc@freebsd.org In-Reply-To: <17B64023-A64A-40DA-9CBC-A601710AB5BB@vicor.com> 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> Content-Type: text/plain Organization: Vicor, Inc Date: Thu, 04 Nov 2010 18:09:28 -0700 Message-Id: <1288919368.7362.35.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.0.2 (2.0.2-41.el4) Content-Transfer-Encoding: 7bit X-Scan-Signature: 677e561b8633df40e6a0c0d8fcab247f X-Scan-Host: postoffice.vicor.com Cc: 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: Fri, 05 Nov 2010 01:09:34 -0000 And now... for the piece de resistance! On Tue, 2010-11-02 at 20:48 -0700, Devin Teske wrote: > On Nov 2, 2010, at 6:06 PM, Devin Teske wrote: > > > On Wed, 2010-10-20 at 23:46 -0700, Devin Teske wrote: > >> On Oct 19, 2010, at 10:50 AM, Devin Teske wrote: > >> > >>> On Mon, 2010-10-18 at 17:39 -0700, Devin Teske wrote: > >>>> On Wed, 2010-10-13 at 12:05 -0700, Devin Teske wrote: > >>>>> On Tue, 2010-10-12 at 16:13 -0700, Devin Teske wrote: > >>>>>> Hey all, > >>>>>> > >>>>>> [...] > >>>>>> > >>>>>> Behold... sysrc(8) v2.0 > >>>>>> > >>>>>> #!/bin/sh > >>>>>> [...] > >>>>> > >>>>> Version 2.1 is available here: http://druidbsd.sf.net/ > >>>> > >>>> Version 2.2 now. > >>>> Same links. > >>>> > >>>> I added `-R dir' for specifying an alternate root (other than `/') > >>>> directory (mostly for handling jails). > >>> > >>> Version 2.3 now. > >>> Same links. > >>> > >> > >> Version 2.4 now. > >> Same links. > >> > > > > Version 2.5 now. > > Same links. > > > > That should be all the features that were requested (and some that > > weren't). > > Minor fix ^_^ > Version 2.5.1 now. Woohoo... version 3.0! This version completely does-away with sed(1), replacing entire swaths of code with embedded awk(1) scripts. This gives the script a much-needed performance boost (quantifiably about 623-648% increase in performance given `-Ad' flags on a standard system). I've also added much-needed taint-checking that makes it nearly impossible to break the system. Consequently, as an added bonus, the script now serves as a pre-flight taint-checker for detecting script- errors in all rc.conf(5) files prior to reboot. You can get this wonderful (and free) piece of code for your use at the same ol' place (links below)... > > > > >>> > >>>> > >>>>> > >>>>> Direct links: > >>>>> http://druidbsd.sf.net/download/sysrc.gz (download gzipped) > >>>>> http://druidbsd.sf.net/download/sysrc.txt (view as text) > >>>>> > >>>>> Here's the changes: > >>>>> > >>>> > >>> > > > > > > And here's that good-ol' unified patch to show what's changed... --- sysrc.2_5_1 2010-11-02 20:35:12.000000000 -0700 +++ sysrc 2010-11-04 17:48:17.000000000 -0700 @@ -2,8 +2,8 @@ # -*- tab-width: 4 -*- ;; Emacs # vi: set tabstop=4 :: Vi/ViM # -# Revision: 2.5.1 -# Last Modified: November 2nd, 2010 +# Revision: 3.0 +# Last Modified: November 4th, 2010 ############################################################ COPYRIGHT # # (c)2010. Devin Teske. All Rights Reserved. @@ -30,6 +30,9 @@ # SUCH DAMAGE. # # AUTHOR DATE DESCRIPTION +# dteske 2010.11.04 Add taint checking. +# dteske 2010.11.04 Comments. +# dteske 2010.11.04 Significant performance enhancements. # dteske 2010.11.02 Fix quotes when replacing null assignment. # dteske 2010.11.02 Preserve leading/trailing whitespace in sysrc_set(). # dteske 2010.11.02 Deprecate lrev() in favor of tail(1)'s `-r' flag. @@ -71,6 +74,15 @@ # RC_DEFAULTS Location of `/etc/defaults/rc.conf' file. # SYSRC_VERBOSE Default verbosity. Set to non-NULL to enable. # +# +# Dependencies (sorted alphabetically): +# +# awk(1) cat(1) chmod(1) chown(8) chroot(8) env(1) +# grep(1) jexec(8) jls(8)* mktemp(1) mv(1) rm(1) +# sh(1) stat(1) tail(1) +# +# *optional +# ############################################################ CONFIGURATION # @@ -109,7 +121,7 @@ SHOW_EQUALS= SHOW_NAME=1 SHOW_VALUE=1 -############################################################ FUNCTION +############################################################ FUNCTIONS # have $anything # @@ -294,7 +306,7 @@ sysrc_get() # clean_env --except RC_CONFS RC_DEFAULTS - . "$RC_DEFAULTS" + . "$RC_DEFAULTS" > /dev/null 2>&1 # # If the query is for `rc_conf_files' then store the value that @@ -312,7 +324,7 @@ sysrc_get() # [ "$RC_CONFS" ] && rc_conf_files="$RC_CONFS" - source_rc_confs + source_rc_confs > /dev/null 2>&1 # # If the query was for `rc_conf_files' AND after calling @@ -355,6 +367,7 @@ sysrc_get() sysrc_find() { local varname="$1" + local regex="^[[:space:]]*$varname=" local rc_conf_files="$( sysrc_get rc_conf_files )" local conf_files= local file @@ -389,7 +402,7 @@ sysrc_find() # for file in $conf_files; do [ -f "$file" -a -r "$file" ] || continue - if grep -q "^[[:space:]]*$varname=" $file; then + if grep -Eq "$regex" $file; then echo $file return $SUCCESS fi @@ -433,7 +446,7 @@ sysrc_set() if [ "$RC_CONFS" ]; then file="${RC_CONFS%%[$IFS]*}" else - file="$( sysrc_get "rc_conf_files%%[$IFS]*" )" + file=$( sysrc_get "rc_conf_files%%[$IFS]*" ) fi fi @@ -448,71 +461,13 @@ sysrc_set() # # Perform sanity checks. # - if [ ! -w $file ]; then + if [ ! -w "$file" ]; then eprintf "\n%s: cannot create %s: Permission denied\n" \ "$progname" "$file" return $FAILURE fi # - # Operate on the matching file, replacing only the last occurrence. - # - local __IFS="$IFS" - local new_contents="`tail -r $file 2> /dev/null | \ - ( found= - IFS= - while read -r LINE; do - # If already found, just spew... - if [ "$found" ]; then - echo "$LINE" - continue - fi - - # - # Determine what type of assignment is being performed - # and append the proper expression to accurately replace - # the current value. - # - # NOTE: The base regular expression below should match - # functionally the regex used by sysrc_find(). - # - regex="^([[:space:]]*$varname=)" - if echo "$LINE" | grep -Eq "$regex'"; then - # found assignment w/ single-quoted value - found=1 - regex="$regex(')([^']*)('{0,1})" - elif echo "$LINE" | grep -Eq "$regex"'"'; then - # found assignment w/ double-quoted value - found=1 - regex="$regex"'(")([^\\\\]*\\\\")*[^"]*("{0,1})' - elif echo "$LINE" | grep -Eq "$regex[^[:space:]]"; then - # found assignment w/ non-quoted value - found=1 - regex="$regex()([^[:space:]]*)()" - - # Use quotes if replacing with multi-word value - [ "${new_value%[$__IFS]*}" != "$new_value" ] \ - && new_value='"'"$new_value"'"' - elif echo "$LINE" | grep -Eq "$regex"; then - # found null-assignment - found=1 - regex="$regex()()()" - - # Always use quotes - new_value='"'"$new_value"'"' - fi - - # Do the deed... - [ "$found" ] && LINE="$( echo "$LINE" \ - | sed -re "s/$regex/\1\2$new_value\4/" )" - - echo "$LINE" - done - ) | tail -r`" - - [ "$new_contents" ] || return $FAILURE - - # # Create a new temporary file to write to. # local tmpfile="$( mktemp -t "$progname" )" @@ -524,19 +479,116 @@ sysrc_set() # temporary file over the destination, the destination will inherit the # permissions from the temporary file). # - chmod $( stat -f '%#Lp' "$file" ) "$tmpfile" 2> /dev/null + chmod "$( stat -f '%#Lp' "$file" )" "$tmpfile" 2> /dev/null # # Fixup ownerhsip. The destination file _is_ writable (we tested # earlier above). However, this will fail if we don't have sufficient # permissions (so we throw stderr into the bit-bucket). # - chown $( stat -f '%u:%g' "$file" ) "$tmpfile" 2> /dev/null + chown "$( stat -f '%u:%g' "$file" )" "$tmpfile" 2> /dev/null + + # + # Protect our awk(1) script from quotes in new_value + # + local awk_new_value="$( echo "$new_value" \ + | awk '{ gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); print }' )" + + # + # Generate an awk(1) script to find/replace the appropriate line. + # If a line suitable-of-replacement is not found, awk will return + # error-status, indicating that we should append the new value. + # + + local awkscript apos="'" quot='"' bquot='\"' bbtick='\`' + local regex="^[[:space:]]*$varname=" + #NOTE: This should be the same regex as used by sysrc_find() + + awkscript=$( cat << EOF + BEGIN { retval = 0; found = 0 } + { + # If already found... just spew + if ( found ) { print; next } + + # Does this line match an assignment to our variable? + if ( ! match(\$0, /$regex/) ) { print; next } + + # Save important match information + found = 1 + matchlen = RSTART + RLENGTH - 1 + + # Store the value text for later munging + value = substr(\$0, matchlen + 1, length(\$0) - matchlen) + + # Store the first character of the value + t1 = t2 = substr(value, 0, 1) + + # Assignment w/ back-ticks, expression, or misc. + # We ignore these since we did not generate them + # + if ( t1 ~ /[$bbtick\\\$\\\\]/ ) + { retval = 1; print; next } + + # Assignment w/ single-quoted value + else if ( t1 == "$apos" ) { + sub(/^$apos[^$apos]*/, "", value) + if ( length(value) == 0 ) t2 = "" + sub(/^$apos/, "", value) + } + + # Assignment w/ double-quoted value + else if ( t1 == "$bquot" ) { + sub(/^$quot(.*\\\\+$quot)*[^$quot]*/, "", value) + if ( length(value) == 0 ) t2 = "" + sub(/^$quot/, "", value) + } + + # Assignment w/ non-quoted value + else if ( t1 ~ /[^[:space:];#]/ ) { + t1 = t2 = "$bquot" + sub(/^[^[:space:]]*/, "", value) + } + + # Null-assignment + else if ( t1 ~ /[[:space:]];#]/ ) + { t1 = t2 = "$bquot" } + + printf "%s%c%s%c%s\n", substr(\$0, 0, matchlen), \ + t1, "$awk_new_value", t2, value + } + END { exit retval } +EOF + ) + + # + # Operate on the matching file, replacing only the last occurrence. + # + local new_contents retval + new_contents=$( tail -r $file 2> /dev/null ) + new_contents=$( echo "$new_contents" | awk "$awkscript" ) + retval=$? + + # + # Write the temporary file contents. + # + echo "$new_contents" | tail -r > "$tmpfile" || return $FAILURE + if [ $retval -ne $SUCCESS ]; then + echo "$varname=\"$new_value\"" >> "$tmpfile" + fi + + # + # Taint-check our results. + # + if ! /bin/sh -n "$tmpfile"; then + eprintf "%s: Not overwriting \`%s' due to %s\n" \ + "$progname" "$file" "previous syntax errors" + rm -f "$tmpfile" + return $FAILURE + fi # - # Write the temporary file contents and move it into place. + # Finally, move the temporary file into place. # - echo "$new_contents" > "$tmpfile" || return $FAILURE mv "$tmpfile" "$file" } @@ -551,49 +603,44 @@ sysrc_set() sysrc_desc() { local varname="$1" + local regex="^[[:space:]]*$varname=" + local vregex="[[:space:]]*[[:alpha:]_][[:alnum:]_]*" + local awkscript + + awkscript=$( cat << EOF + BEGIN { found = 0; buffer = "" } + { + if ( ! found ) + { + if ( ! match(\$0, /$regex/) ) next + + found = 1 + sub(/^[^#]*(#[[:space:]]*)?/, "") + buffer = \$0 + next + } + + if ( !/^[[:space:]]*#/ || + /^[[:space:]]*$vregex=/ || + /^[[:space:]]*#$vregex=/ || + /^[[:space:]]*$/ ) exit + + sub(/(.*#)*[[:space:]]*/, "") + buffer = buffer" "\$0 + } + END \ + { + # Clean up the buffer + sub(/^[[:space:]]*/, "", buffer) + sub(/[[:space:]]*$/, "", buffer) + + print buffer + exit ! found + } +EOF + ) - ( - buffer= - while read LINE; do - case "$LINE" in - $varname=*) - buffer="$LINE" - break - esac - done - - # Return if the variable wasn't found - [ "$buffer" ] || return $FAILURE - - regex='[[:alpha:]_][[:alnum:]_]*=' - while read LINE; do - # - # Stop reading comments if we reach a new assignment - # directive or if the line contains only whitespace - # - echo "$LINE" | grep -q "^[[:space:]]*$regex" && break - echo "$LINE" | grep -q "^[[:space:]]*#$regex" && break - echo "$LINE" | grep -q "^[[:space:]]*$" && break - - # Append new line to buffer - buffer="$buffer -$LINE" - done - - # Return if the buffer is empty - [ "$buffer" ] || return $FAILURE - - # - # Clean up the buffer. - # - regex='^[^#]*\(#[[:space:]]*\)\{0,1\}' - buffer="$( echo "$buffer" | sed -e "s/$regex//" )" - buffer="$( echo "$buffer" | tr '\n' ' ' \ - | sed -e 's/^[[:space:]]*//;s/[[:space:]]*$//' )" - - echo "$buffer" - - ) < "$RC_DEFAULTS" + awk "$awkscript" < "$RC_DEFAULTS" } ############################################################ MAIN SOURCE @@ -632,6 +679,17 @@ done shift $(( $OPTIND - 1 )) # +# Taint-check all rc.conf(5) files +# +errmsg="$progname: Exiting due to previous syntax errors" +/bin/sh -n "$RC_DEFAULTS" || die "$errmsg" +( . "$RC_DEFAULTS" + for i in ${RC_CONFS:-$rc_conf_files}; do + /bin/sh -n "$i" || exit $FAILURE + done +) || die "$errmsg" + +# # Process `-e', `-n', and `-N' command-line options # SEP=': ' @@ -845,9 +903,9 @@ while [ $# -gt 0 ]; do # if [ "$SYSRC_VERBOSE" ]; then - file="$( sysrc_find "$NAME" )" + file=$( sysrc_find "$NAME" ) [ "$file" = "$RC_DEFAULTS" -o ! "$file" ] && \ - file="$( sysrc_get "rc_conf_files%%[$IFS]*" )" + file=$( sysrc_get "rc_conf_files%%[$IFS]*" ) echo -n "$file: " fi @@ -858,9 +916,10 @@ while [ $# -gt 0 ]; do echo "$NAME" sysrc_set "$NAME" "${1#*}" else - echo -n "${SHOW_NAME:+$NAME$SEP}$( - sysrc_get "$NAME" )${SHOW_EQUALS:+\"}" + before=$( sysrc_get "$NAME" ) if sysrc_set "$NAME" "${1#*=}"; then + echo -n "${SHOW_NAME:+$NAME$SEP}" + echo -n "$before${SHOW_EQUALS:+\"}" echo " -> $( sysrc_get "$NAME" )" fi fi -- 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+ ------END GEEK CODE BLOCK------ http://www.geekcode.com/ -> END TRANSMISSION <- From owner-freebsd-rc@FreeBSD.ORG Fri Nov 5 03:18:00 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 0968C1065673 for ; Fri, 5 Nov 2010 03:18:00 +0000 (UTC) (envelope-from cyrille.lefevre-lists@laposte.net) Received: from out6.laposte.net (out5.laposte.net [193.251.214.122]) by mx1.freebsd.org (Postfix) with ESMTP id 91E3D8FC0A for ; Fri, 5 Nov 2010 03:17:59 +0000 (UTC) Received: from out5.laposte.net (unknown [10.98.51.225]) by mwinf8405.laposte.net (SMTP Server) with ESMTP id 564B41C0014B for ; Fri, 5 Nov 2010 03:57:32 +0100 (CET) Received: from meplus.info (localhost [127.0.0.1]) by mwinf8412.laposte.net (SMTP Server) with ESMTP id 3356AE000097; Fri, 5 Nov 2010 03:57:30 +0100 (CET) Received: from [192.168.1.133] (162.64.99-84.rev.gaoland.net [84.99.64.162]) by mwinf8412.laposte.net (SMTP Server) with ESMTP id D550EE000094; Fri, 5 Nov 2010 03:57:24 +0100 (CET) X-ME-UUID: 20101105025725873.D550EE000094@mwinf8412.laposte.net Message-ID: <4CD3731C.6020501@laposte.net> Date: Fri, 05 Nov 2010 03:59:40 +0100 From: Cyrille Lefevre Organization: ACME User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070326 Thunderbird/2.0.0.0 Mnenhy/0.7.5.666 MIME-Version: 1.0 To: Devin Teske 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> In-Reply-To: <1288919368.7362.35.camel@localhost.localdomain> Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: quoted-printable X-me-spamlevel: not-spam X-me-spamrating: 36.000000 X-me-spamcause: OK, (-100)(0000)gggruggvucftvghtrhhoucdtuddrfedtiedrtdejucetggdotefuucfrrhhofhhilhgvmecuoehnohhnvgeqnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd 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: Fri, 05 Nov 2010 03:18:00 -0000 Le 05/11/2010 02:09, Devin Teske a =E9crit : hi, how about something like (untested, but should work) : # no $(cat << EOF needed here, so, no extra \ and $quot and so needed awkscript=3D' # %s/\\$0/$0/;s/\\\\/\\/g BEGIN { ...; regex=3D"^[[:space:]]*" varname "=3D" } =2E.. if ( ! match($0, regex) ) { print; next } =2E.. if ( t1 ~ /[\'\$\\]/ ) =2E.. else if ( t1 =3D=3D apos ) { sub("^" apos "[^" apos "]*", "", value) if ( length(value) =3D=3D 0 ) t2 =3D "" sub("^" apos, "", value) =2E.. else if ( t1 =3D=3D "\"" ) { sub(/^"[^"]*/, "", value) if ( length(value) =3D=3D 0 ) t2 =3D "" sub(/^"/, "", value) =2E.. t1 =3D t2 =3D "\"" =2E.. else if ( t1 ~ /[[:space:]];#]/ ) # parentheses aren't needed here, or wrap them as before t1 =3D t2 =3D "\"" =2E.. printf "%s%c%s%c%s\n", substr(\$0, 0, matchlen), \ t1, awk_new_value, t2, value ' # ... | ... doesn't need a final \ when wrapped after the | local awk_new_value=3D"$( echo "$new_value" | awk '{ gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); print }' )" =2E.. # you missed the " here new_contents=3D$( tail -r "$file" 2> /dev/null ) # 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") of course, same remarks about the later awk script :-) also, %s|/bin/sh|$_PATH_BSHELL| && _PATH_BSHELL=3D/bin/sh PS : for non french user : %s/quot/dquot/;%s/apos/squot/;s/bquotquot/bquot/ Regards, Cyrille Lefevre --=20 mailto:Cyrille.Lefevre-lists@laposte.net From owner-freebsd-rc@FreeBSD.ORG Fri Nov 5 17:41:04 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 0620C1065693 for ; Fri, 5 Nov 2010 17:41:04 +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 DC83A8FC12 for ; Fri, 5 Nov 2010 17:41:02 +0000 (UTC) Received: from [208.206.78.30] (port=52808 helo=dt.vicor.com) by postoffice.vicor.com with esmtpsa (SSLv3:RC4-MD5:128) (Exim 4.71) (envelope-from ) id 1PEQHa-0000QY-RV; Fri, 05 Nov 2010 10:41:02 -0700 From: Devin Teske To: Cyrille Lefevre In-Reply-To: <4CD3731C.6020501@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> Content-Type: text/plain; charset=UTF-8 Organization: Vicor, Inc Date: Fri, 05 Nov 2010 10:40:58 -0700 Message-Id: <1288978858.7362.154.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: 2bdb55ca3ea6de4a29b1210eedbadebc 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: Fri, 05 Nov 2010 17:41:04 -0000 On Fri, 2010-11-05 at 03:59 +0100, Cyrille Lefevre wrote: > Le 05/11/2010 02:09, Devin Teske a =C3=A9crit : >=20 > hi, how about something like (untested, but should work) : >=20 > # no $(cat << EOF needed here, so, no extra \ and $quot and so needed The `$(cat << EOF' is very much needed. The expansion rules for text appearing between "< awkscript=3D' > # %s/\\$0/$0/;s/\\\\/\\/g > BEGIN { ...; regex=3D"^[[:space:]]*" varname "=3D" } Won't work. You've replaced my usage of an embedded here-document (which performs parameter expansion) with single-quote assignment (which does not perform parameter expansion). 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). So right off the bat, your awk script will fail because regex will be assigned a value of: ^[[:space:]]*=3D Now, again, you can get around this problem by using a compound string, like so: awkscript=3D' BEGIN { ...; regex=3D"^[[:space:]]*'"$varname"'=3D } But that's not as readable because it requires you to mentally switch from reading awk code to reading shell, back to awk in the same line. > ... > if ( ! match($0, regex) ) { print; next } Fail due to bad regex value (see prior comments) > ... > if ( t1 ~ /[\'\$\\]/ ) Since we're picking nits: - the backslash before the apostrophe is not needed. > ... > else if ( t1 =3D=3D apos ) { apos needs to be a shell-expanded parameter/variable, otherwise you'll be forced to declare apos in the awkscript, which itself (without using compound strings) will force vim syntax highlighting to break (something that's not really important for the awkscript itself, but it's rather disconcerting to see entire oceans of miscolored text AFTER the embedded here-document). > sub("^" apos "[^" apos "]*", "", value) > if ( length(value) =3D=3D 0 ) t2 =3D "" > sub("^" apos, "", value) Same as above. > ... > else if ( t1 =3D=3D "\"" ) { > sub(/^"[^"]*/, "", value) > if ( length(value) =3D=3D 0 ) t2 =3D "" > sub(/^"/, "", value) $quot was used to protect the vim syntax highlighting from stray marks. This block breaks that whereas my block preserved highlighting (using vim version 7.2.411 here). > ... > t1 =3D t2 =3D "\"" Again, stray mark. To understand why, it's because back-slash expansion is not performed within a here-document, so syntax-highlighting sees three quotes, _not_ an escaped-quote surrounded by two double-quotes. > ... > else if ( t1 ~ /[[:space:]];#]/ ) > # parentheses aren't needed here, or wrap them as before > t1 =3D t2 =3D "\"" Huh? My code: else if ( t1 ~ /[^[:space:];#]/ ) { t1 =3D t2 =3D "$bquot" sub(/^[^[:space:]]*/, "", value) } Your suggested replacement (???): else if ( t1 ~ /[[:space:]];#]/ ) t1 =3D t2 =3D "\"" *cough* You've removed the "NOT" operator (^) from my character class expansion, removed the substitution line, and killed the braces. This code does not do the same thing. Either that, or you were attempting to combine the detection of the non- quoted value-assignment and the null-assignment. This is wrong. These cannot be combined or else the results differ. > ... > printf "%s%c%s%c%s\n", substr(\$0, 0, matchlen), \ > t1, awk_new_value, t2, value > ' Just as before with $regex (which had $varname which is $1 which is the positional parameter passed to the shell function), this will fail because awk_new_value is not defined by awk. Further, you've forgotten to conver \$0 to $0 (considering that you've switched the context from an embedded here-document which performs parameter expansion -- hence the escape of the dollar-sign -- versus a single-quoted assignment which does _NOT_ perform parameter expansion -- and hence no need for the preceding back-slash). >=20 > # ... | ... doesn't need a final \ when wrapped after the | > local awk_new_value=3D"$( echo "$new_value" | > awk '{ gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); print }' )" Wrong. Fail. And here's why... You are correct that a $( ... ) block can traverse newlines. However, what $( ... ) functional performs is a sub-shell. Each line within the $( ... ) syntax is taken as a single-line of shell to be executed. Therefore, by deleting the back-slash at the end of the line, you've turned one statement into two. One statement: echo "$new_value" | \ awk '{ gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); print }' (also written as -- if you have the guts to stomach line-wrapping given ts=3D8 indentation within the script) echo "$new_value" | awk '{ gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); print }' However, you've turned the above into two statements: First statement: echo "$new_value" | Second statement: awk '{ gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); print }' The first statement will cause a shell syntax error within the sub- shell. > ... > # you missed the " here > new_contents=3D$( tail -r "$file" 2> /dev/null ) No, I did not. And here's why... Many people are confused on this issue. Let me clarify. When you make an assignment to a variable in the bare name-space using the $( ... ) or ` ... ` syntaxes, quotes are optional. When you make an assignment to a variable in the positional argument name-space using the $( ... ) or ` ... ` syntaxes, quotes are _required_ (if you want to preserve spaces). Valid Examples: # bare name-space foo=3D$( echo " 123 456 ") echo "'$foo'" # produces: ' 123 456 ' # bare name-space foo=3D` echo " 123 456 " ` echo "'$foo'" # produces: ' 123 456 ' # positional argument name-space env foo=3D"$( echo " 123 456 " )" echo "'$foo'" # produces: ' 123 456 ' # positional argument name-space (within a function) local foo=3D"$( echo " 123 456 " )" echo "'$foo'" # produces: ' 123 456 ' # positional argument name-space [ "$( echo " 123 456 " )" =3D "xxx" ] # works fine Invalid Examples: # positional argument name-space env foo=3D$( echo " 123 456 " ) # produces: env: 123: No such file or directory # positional argument name-space (within a function) local foo=3D$( echo " 123 456 " ) # produces: local: 123: bad variable name # positional argument name-space [ $( echo " 123 456 " ) =3D "xxx" ] # produces: [: 123: unexpected operator > # 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") No. You are confused about the order in which the shell performs each different word expansion. Expansion of escape sequences is not performed on expanded parameters. Here's proof: #!/bin/sh foo=3D'123\456' echo "'$foo'" # produces: '123\456' Here's the one-liner proof (first with compound strings): /bin/sh -c 'foo=3D'"'"'123\456'"'"'; echo "'"'"'$foo'"'"'"' again (with alternate-form compound strings): /bin/sh -c "foo=3D'"'123\456'"'; echo "'"'"'"'$foo'"'"'"' again (without compound strings; with escapes): /bin/sh -c "foo=3D'123\\456'; echo \"'\$foo'\"" again (with compound strings and escapes): /bin/sh -c "foo=3D'"'123\456'"'; echo \"'\$foo'\"" again (simpler -- as quotes are optional on second part) /bin/sh -c "foo=3D'123\\456'; echo \$foo" again: /bin/sh -c 'foo=3D'"'"'123\456'"'"'; echo $foo' All of the above produce the same output (well, almost, the last two lack surrounding apostrophes -- which were themselves illustrative of the fact that parameter expansion within double-quotes, even with surrounding text, also lacks escape-sequence expansion) and serve to illustrate that it is a common misconception that escape-sequences within variables need imply that one needs to use printf instead of echo. Rather, the truth is that one never needs to escape the escape- sequences within a variable unless the command-line that the parameter was expanded in is itself then re-evaluated (e.g. foo=3D'\\' && eval echo $foo). It is perfectly safe to pass a variable containing escape-sequences, newlines, spaces, variables, etc. to echo. Just make sure that you enclose the variable is quoted (and even then, the only thing you lose by not having it quoted is that multiple spaces will become one -- because rather than appearing as one argument, it will appear as multiple arguments and echo cannot conceivably preserve spaces between arguments because it is the shell that obliterates the spaces between positional parameters, not echo) >=20 > of course, same remarks about the later awk script :-) Which would be equally as faulty. Above remarks to the your same remarks about the later awk script. :-) >=20 > also, %s|/bin/sh|$_PATH_BSHELL| && _PATH_BSHELL=3D/bin/sh What could this possibly buy you? Other than increased CPU cycles caused by foisting further expansions upon the runtime execution? This script is coded for a single target: FreeBSD-CURRENT Abstracting the shell in the above manner gives you nothing, though I understand why you'd want it. Alternatively, if you really desired the ability to switch the shell, you'd do something like: _SH=3D$SHELL ... $_SH ... This would allow you two nice things... 1. If someone modifies your script to change the invocation line: from: #!/bin/sh to: #!/usr/bin/env sh or: #!/usr/bin/env bash or: #!/usr/local/bin/bash or: #!/bin/bash or: #!/usr/bin/bash etc... _SH will inherit the correct value from $SHELL and use the same script interpreter that is interpreting the script itself. 2. If someone modifies your script to change the _SH line: from: _SH=3D$SHELL to: _SH=3D/bin/sh or: _SH=3D/usr/bin/bash etc... The script can use a different sub-interpreter than the invocation interpreter. However, I will use neither for two very good reasons: a. when I do call /bin/sh in certain places, I need to pass specific command-line options were may be shell specific, and thus it should not be considered allowable for some user to come along and change the following: /bin/sh -n /etc/defaults/rc.conf to use some other shell because some other shell (beit inheritance of the invocation shell or otherwise) may not support the `-n' flag (which btw, checks syntax of a script without executing it). b. If /bin/sh doesn't exist, you've got real problems. Least to mention, it's likely that script itself will not execute considering that the invocation line is itself: #!/bin/sh If you truly want to write shell agnostic code, you can, and I have. This involves using env(1) to find your shell by-name rather than by- path (and env(1) is always at /usr/bin/env on every POSIX-compliant OS including BSD*, SunOS, *BSD, Solaris, Linux, Cygwin, and Mac OS X). It also involves using a dependency-calculating structure much like the first iterations of this script (see the beginnings of this thread over on freebsd-hackers@ mailing list archives under the "sysconf" thread). However, as I'll point out again, this script is coded for a single target (FreeBSD-Current) and thus will not employ such abstractions so commonly associated with platform aganosticism and/or embeddedOS programming. In other words, we will rely on things that exist in the base structure of FreeBSD and make no qualms about directly referencing pathnames that should exist. And in mentioning this, here's the current dependency list: # Dependencies (sorted alphabetically): # # awk(1) cat(1) chmod(1) chown(8) chroot(8) env(1) # grep(1) jexec(8) jls(8)* mktemp(1) mv(1) rm(1) # sh(1) stat(1) tail(1) # # *optional Last, but not least... Some pathnames have been hard-coded for security purposes. For example, in the script, you will find three instances where PATH expansion is not trusted and full-pathnames are used: /bin/sh (6 occurrences) /usr/sbin/jexec (2 occurrences) /usr/sbin/chroot (1 occurrence) The only reason I can possibly see to assign these full paths to variables would be if we were going to target another OS which puts these in different places. However, as it currently stands, this script targets FreeBSD, and all versions of FreeBSD agree on the location of these utilities. If it is discovered that this script is even usable on another BSD-style OS that uses the rc.conf(5) files in a similar manner (that is, /etc/defaults/rc.conf must exist and must declare the source_rc_confs() function and must also define the rc_conf_files variable), then I will consider localizing the paths to these executables to variables IF (and only IF) said target platform uses different pathnames. However, as it currently, stands, even MidnightBSD (which has taken this script into its base -- Thanks Lucas Holt!) has these executables right where I expect them to be. >=20 > PS : for non french user : > %s/quot/dquot/;%s/apos/squot/;s/bquotquot/bquot/ Might you have instead meant: %s/[^b]?quot/dquot/g %s/apos/squot/g Not sure where you got the bquotquot (not in my code). NOTE: The leading '%' indicates to me that perhaps you meant this as a vi/vim find/replace command (no '%' would instead indicate sed(1) or perl(1)). You cannot perform multiple '%s///' operators separated by a semi-colon. You would get the error "E488: Trailing characters" in vim and the error "Usage: [line [,line]] s [[/;]RE[/;]repl[/;] [cgr] [count] [#lp]]." in vi (but I digress from picking nits) >=20 > 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. -> END TRANSMISSION <- From owner-freebsd-rc@FreeBSD.ORG Sat Nov 6 01:30:32 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 B1E2F106566B for ; Sat, 6 Nov 2010 01:30:32 +0000 (UTC) (envelope-from cyrille.lefevre-lists@laposte.net) Received: from out1.laposte.net (out2.laposte.net [193.251.214.119]) by mx1.freebsd.org (Postfix) with ESMTP id 433C18FC0C for ; Sat, 6 Nov 2010 01:30:31 +0000 (UTC) Received: from meplus.info (localhost [127.0.0.1]) by mwinf8213.laposte.net (SMTP Server) with ESMTP id 825327000091; Sat, 6 Nov 2010 02:30:30 +0100 (CET) Received: from [192.168.1.133] (162.64.99-84.rev.gaoland.net [84.99.64.162]) by mwinf8213.laposte.net (SMTP Server) with ESMTP id 0AEC27000089; Sat, 6 Nov 2010 02:30:27 +0100 (CET) X-ME-UUID: 20101106013028448.0AEC27000089@mwinf8213.laposte.net Message-ID: <4CD4B040.1000804@laposte.net> Date: Sat, 06 Nov 2010 02:32:48 +0100 From: Cyrille Lefevre Organization: ACME User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070326 Thunderbird/2.0.0.0 Mnenhy/0.7.5.666 MIME-Version: 1.0 To: Devin Teske 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> In-Reply-To: <1288978858.7362.154.camel@localhost.localdomain> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-me-spamlevel: not-spam X-me-spamrating: 30.000000 X-me-spamcause: OK, (-250)(0000)gggruggvucftvghtrhhoucdtuddrfedtiedrtdekucetggdotefuucfrrhhofhhilhgvmecuoehnohhnvgeqnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucdlqddutddtmdenfhhunhgtthhiohhnqegsvghgihhnqegvnhguucdlqdehtddm 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 01:30:32 -0000 Le 05/11/2010 18:40, Devin Teske a =E9crit : > On Fri, 2010-11-05 at 03:59 +0100, Cyrille Lefevre wrote: >> Le 05/11/2010 02:09, Devin Teske a =E9crit : you don't have to comment every line w/ 10+ lines of comments. I don't agress you, it was just a proposal which is IMHO more readable. however, it's your code and you make whatever you want w/ it. the more important thing is that you understand it, well, except if someone else have to maintain it also :-) >> 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). you're wrong, the assignment is done later in : awk -v varname=3D"$varname" ... "$awkscript" > So right off the bat, your awk script will fail because regex will be > assigned a value of: >=20 > ^[[:space:]]*=3D wrong too, $ v=3D123; awk -v v=3D"$v" 'BEGIN{ r=3D"^[[:space:]]*"v"=3D"; print r; ex= it}' ^[[:space:]]*123=3D >> ... >> if ( t1 ~ /[\'\$\\]/ ) >=20 > Since we're picking nits: > - the backslash before the apostrophe is not needed. right :-) >> ... >> else if ( t1 =3D=3D apos ) { >=20 > apos needs to be a shell-expanded parameter/variable, otherwise you'll > be forced to declare apos in the awkscript, which itself (without using= > compound strings) will force vim syntax highlighting to break (somethin= g > that's not really important for the awkscript itself, but it's rather > disconcerting to see entire oceans of miscolored text AFTER the embedde= d > here-document). done in awk -v apos=3D"'" ... "$awkscript" below >> ... >> else if ( t1 ~ /[[:space:]];#]/ ) >> # parentheses aren't needed here, or wrap them as before >> t1 =3D t2 =3D "\"" bad copy/paste, I was talking about the later one (null assignment) # 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. >> ... >> printf "%s%c%s%c%s\n", substr(\$0, 0, matchlen), \ >> t1, awk_new_value, t2, value >> ' >=20 > Just as before with $regex (which had $varname which is $1 which is the= > positional parameter passed to the shell function), this will fail > because awk_new_value is not defined by awk. see below too ;^) > Further, you've forgotten to conver \$0 to $0 (considering that you've no, look at the # %s/\\$0/$0/;s/\\\\/\\/g abobe >> # ... | ... 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. no, no, no, did you tried it ? your syntax : x=3D$(echo x \ | sed s,x,y,) echo $x the usual syntax : x=3D$(echo x | sed s,x,y,) echo $x both should print y or the shell is buggy ? so, as I told you, the \ isn't needed after a |. >> # you missed the " here >> new_contents=3D$( tail -r "$file" 2> /dev/null ) >=20 > No, I did not. And here's why... I was talking about the ones around $file, not the ones around $() >> # 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") 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 ? >> also, %s|/bin/sh|$_PATH_BSHELL| && _PATH_BSHELL=3D/bin/sh it's just an habit to hardcode path within variables and a proposal. > Not sure where you got the bquotquot (not in my code). in my example, the %s/quot/dquot/ statment turns bquot to bquotquot :-) > perl(1)). You cannot perform multiple '%s///' operators separated by a > semi-colon. You would get the error "E488: Trailing characters" in vim it was just a synthetic form of writing, no more. Regards, Cyrille Lefevre --=20 mailto:Cyrille.Lefevre-lists@laposte.net 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 <- From owner-freebsd-rc@FreeBSD.ORG Sat Nov 6 14:34:42 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 BAB431065673 for ; Sat, 6 Nov 2010 14:34:42 +0000 (UTC) (envelope-from cyrille.lefevre-lists@laposte.net) Received: from out3.laposte.net (out4.laposte.net [193.251.214.121]) by mx1.freebsd.org (Postfix) with ESMTP id 4E0B08FC0C for ; Sat, 6 Nov 2010 14:34:41 +0000 (UTC) Received: from meplus.info (localhost [127.0.0.1]) by mwinf8316.laposte.net (SMTP Server) with ESMTP id 9084A7000095; Sat, 6 Nov 2010 15:34:40 +0100 (CET) Received: from [192.168.1.133] (162.64.99-84.rev.gaoland.net [84.99.64.162]) by mwinf8316.laposte.net (SMTP Server) with ESMTP id 4C1A4700008D; Sat, 6 Nov 2010 15:34:38 +0100 (CET) X-ME-UUID: 20101106143439311.4C1A4700008D@mwinf8316.laposte.net Message-ID: <4CD56812.8080502@laposte.net> Date: Sat, 06 Nov 2010 15:37:06 +0100 From: Cyrille Lefevre Organization: ACME User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070326 Thunderbird/2.0.0.0 Mnenhy/0.7.5.666 MIME-Version: 1.0 To: Devin Teske 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> <1289013402.7362.282.camel@localhost.localdomain> In-Reply-To: <1289013402.7362.282.camel@localhost.localdomain> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-me-spamlevel: not-spam X-me-spamrating: 30.799999 X-me-spamcause: OK, (-230)(0000)gggruggvucftvghtrhhoucdtuddrfedtiedrtdelucetggdotefuucfrrhhofhhilhgvmecuoehnohhnvgeqnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucdlqddutddtmdenfhhrvggvsghsugdvgiculddqvddtmdenuefuffculddquddtmd 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 14:34:42 -0000 Le 06/11/2010 04:16, Devin Teske a =C3=A9crit : > 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 : > Ah, I was also confused by "parentheses" -- I've always referred to > those as braces (of the "curly" persuasion). well, english isn't my natural language, so, sometimes, I used the wrong word... :-) >>>> # ... | ... doesn't need a final \ when wrapped after the | >>>> local awk_new_value=3D"$( echo "$new_value" | >>>> awk '{ gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); print }' )" >>> >>> Wrong. Fail. And here's why... >>> >>> You are correct that a $( ... ) block can traverse newlines. >>> >>> However, what $( ... ) functional performs is a sub-shell. Each line >>> within the $( ... ) syntax is taken as a single-line of shell to be >>> executed. >>> >>> Therefore, by deleting the back-slash at the end of the line, you've >>> turned one statement into two. >> >> no, no, no, did you tried it ? >> >> your syntax : >> x=3D$(echo x \ >> | sed s,x,y,) >> echo $x >> >> the usual syntax : >> x=3D$(echo x | >> sed s,x,y,) >> echo $x >> >> both should print y or the shell is buggy ? >> >> so, as I told you, the \ isn't needed after a |. >=20 > no, no, no, did YOU try it? well, you're not undertandnig me, again :-) I am talking about putting the pipe to the end of the first line, not to the begin of following the line. your examples doesn't show this case, so, try it again :-) > In this case, I argue that I don't need quotes around $file, because th= e > operating system itself (as you can see above; notably lines 1, 3, 7 an= d > 8) does not support values of rc_conf_files that contain spaces. may be the operating system is wrong :-) it's a usual habit to protect everything (files, parameters, etc) w/ " in case of spaces except the exception where you want to do word splitting, which is a rare case finally. also, it is to be concistent w/ the rest of the script where evrery occurence of a file is " protected, so, why not here ! in this case, why do you protect $tmpfile which is generated bu mktemp (probably w/o spaces), etc. >>>> # you may want to use printf "%s" "$new_contents" instead of echo >>>> # to avoid \ sequences interpretation if any about echo vs printf : echo 'x\tx' =3D> x x vs printf '%s' "x\tx' =3D> x\tx the usual problem is that printf isn't a builtin, this imply performance degradation... alternatively, you may want to use the -E option to echo if supported (freebsd seems to support it, so, use it). same remark about read, always use the -r option... for the history, echo is one of the more unportable command of the unix universe ! http://www.in-ulm.de/~mascheck/various/echo+printf/ > Make sure you use bourne-shell for your tests. >=20 > No shell system-level scripts within FreeBSD use bash (and rightly so, > as it's not part of the base distribution). I'm not talking bash in any case, I hate bash for many reasons, ksh is one of the best shell, except maybe zsh, but I don't know this one, but I'm talking posix shell w/o any problem :-) > Well... I have to say thank you. >=20 > I'm somewhat new to marrying awk(1) w/ sh(1). I do have to say that `-v= > key=3Dvalue' is very handy! >=20 > 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! you're welcome. Regards, Cyrille Lefevre --=20 mailto:Cyrille.Lefevre-lists@laposte.net From owner-freebsd-rc@FreeBSD.ORG Sat Nov 6 18:14: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 04C4A106564A for ; Sat, 6 Nov 2010 18:14: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 D48F28FC0A for ; Sat, 6 Nov 2010 18:14:45 +0000 (UTC) Received: from [71.202.142.31] (port=62675 helo=[192.168.1.93]) by postoffice.vicor.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.71) (envelope-from ) id 1PEnHl-0008CH-Nn; Sat, 06 Nov 2010 11:14:45 -0700 Mime-Version: 1.0 (Apple Message framework v1081) From: Devin Teske In-Reply-To: <4CD56812.8080502@laposte.net> Date: Sat, 6 Nov 2010 11:14:41 -0700 Message-Id: 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> <1289013402.7362.282.camel@localhost.localdomain> <4CD56812.8080502@laposte.net> To: Cyrille Lefevre X-Mailer: Apple Mail (2.1081) X-Scan-Signature: 806f166ab34f21e869604b13d14520b1 X-Scan-Host: postoffice.vicor.com Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.5 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 18:14:46 -0000 On Nov 6, 2010, at 7:37 AM, Cyrille Lefevre wrote: >=20 > Le 06/11/2010 04:16, Devin Teske a =E9crit : >> On Sat, 2010-11-06 at 02:32 +0100, Cyrille Lefevre wrote: >>> Le 05/11/2010 18:40, Devin Teske a =E9crit : >>>> On Fri, 2010-11-05 at 03:59 +0100, Cyrille Lefevre wrote: >>>>> Le 05/11/2010 02:09, Devin Teske a =E9crit : >=20 >> Ah, I was also confused by "parentheses" -- I've always referred to >> those as braces (of the "curly" persuasion). >=20 > well, english isn't my natural language, so, sometimes, I used the = wrong > word... :-) >=20 >>>>> # ... | ... 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 |. >>=20 >> no, no, no, did YOU try it? >=20 > well, you're not undertandnig me, again :-) > I am talking about putting the pipe to the end of the first line, not = to > the begin of following the line. your examples doesn't show this case, > so, try it again :-) Ah-so,... I am the grasshopper (not the walrus). A trailing-pipe appears to be a method of getting the shell to continue = the read to the next line. Quite novel and nice, indeed! Thank you for = that pearl. This does work: $ /bin/sh -c 'x=3D$(echo x |^V^J sed s,x,y,)^V^J echo $x' y >=20 >> 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. >=20 > may be the operating system is wrong :-) > it's a usual habit to protect everything (files, parameters, etc) w/ " > in case of spaces except the exception where you want to do word > splitting, which is a rare case finally. > also, it is to be concistent w/ the rest of the script where evrery > occurence of a file is " protected, so, why not here ! > in this case, why do you protect $tmpfile which is generated bu mktemp > (probably w/o spaces), etc. Therein lies the reasoning... it's a reminder for me. I'm still = determining whether this is truly a bug [in FreeBSD] -- and worth filing = a PR -- or not. Should we take the stance that somebody would have to be insane to do = something like this: 1. Edit /etc/defaults/rc.conf 2. change the rc_conf_files variable 3. to some value that breaks either the: - for-loop - the case statement - `-r' test-case - or the `.' source statement of the source_rc_confs function or do we just patch the OS? Just been sleeping on that one for a few days. >=20 >>>>> # you may want to use printf "%s" "$new_contents" instead of echo >>>>> # to avoid \ sequences interpretation if any >=20 > about echo vs printf : >=20 > echo 'x\tx' =3D> x x > vs > printf '%s' "x\tx' =3D> x\tx I think you meant this: $ /bin/sh -c "type echo; echo 'x\\tx'" echo is a shell builtin x\tx $ /bin/sh -c "type echo; echo -e 'x\\tx'" echo is a shell builtin x x The echo built-in will not expand escape-sequences unless -e is passed. And echo(1) (/bin/echo) is dumb -- it doesn't support escape-sequences = nor `-e' at all. For the record, bash works the same as sh. and csh/tcsh work like = /bin/echo So, there should be no concern about expanding escape-sequences unless = all of the following is true: a. You're using sh, bash, or something similar (not csh or tcsh) b. You pass `-e' as the first positional argument >=20 > the usual problem is that printf isn't a builtin, Wow, it changed... (I guess we were stuck under a rock) $ uname -spr FreeBSD 4.11-STABLE i386 $ /bin/sh -c 'type printf' printf is a shell builtin $ strings /bin/sh | grep '\$FreeBSD:' | grep printf $FreeBSD: src/usr.bin/printf/printf.c,v 1.12.6.7 2004/03/12 23:33:10 = cperciva Exp $ $FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.6 1999/08/28 00:00:55 peter = Exp $ to $ uname -spr FreeBSD 8.1-RELEASE i386 $ /bin/sh -c 'type printf' printf is /usr/bin/printf =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D = http://www.freebsd.org/cgi/cvsweb.cgi/src/bin/sh/Makefile.diff?r1=3D1.31;r= 2=3D1.32;hideattic=3D0;f=3Dh src/bin/sh/Makefile,v1.32 Tue Nov 20 18:33:58 2001 UTC (8 years, 11 = months ago) by knu Remove the printf builtin command from sh(1), which command is not used so often that it's worth keeping it as a builtin. Now that all the printf invocations from within the system startup scripts, we can safely remove it. Urgef by: sheldonh :) No MFC is planned so far because it may break compatibility and violate = POLA. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Of course agreed that invoking an external printf would cause a = performance-hit. > this imply performance > degradation... alternatively, you may want to use the -E option to = echo > if supported (freebsd seems to support it, so, use it). > same remark about read, always use the -r option... I think you meant `-e', I'm not familiar with `-E', is that the opposite = of `-e' (as in, "don't expand escape-sequences")? Use of `-r' depends. I find that it's not enough to say "always use it". = 50% of the cases I've come across should not use it while the other half = should. It really depends on whether you want to pick up the contents of = the next line should there be a trailing back-slash at the end of the = first line read. >=20 > for the history, echo is one of the more unportable command of the = unix > universe ! >=20 > http://www.in-ulm.de/~mascheck/various/echo+printf/ That's a great page! But alas (both by experience and if I'm reading the tables you provided = correctly)... all of the BSD's (that is, since BSD-based OSes are the = only OSes that would need rc.conf(5) type management provided by this = script) all agree on the echo built-in functionality... escape-sequences = are ignored unless -e is passed. >=20 >> Make sure you use bourne-shell for your tests. >>=20 >> No shell system-level scripts within FreeBSD use bash (and rightly = so, >> as it's not part of the base distribution). >=20 > I'm not talking bash in any case, I hate bash for many reasons, ksh is > one of the best shell, except maybe zsh, but I don't know this one, = but > I'm talking posix shell w/o any problem :-) I see the light!!! This finally explains a lot. Yes, ksh switches the echo built-in functionality to expand = escape-sequences by default. To reverse the default functionality, you = pass `-E' (to _not_ expand escape-sequences). You're right, I hadn't considered that portability issue because the = script is programmed in sh(1), not ksh(1). Thanks for lookin' out = though. >=20 >> Well... I have to say thank you. >>=20 >> I'm somewhat new to marrying awk(1) w/ sh(1). I do have to say that = `-v >> key=3Dvalue' is very handy! >>=20 >> 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! >=20 > you're welcome. >=20 > Regards, >=20 > Cyrille Lefevre > --=20 > mailto:Cyrille.Lefevre-lists@laposte.net >=20 >=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 <-