Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Sat, 2010-10-23 at 15:20 +0400, Anthony Pankov wrote: > Greetings. > > Just for note. > > Some time ago i thought about the same problem. > I started something then had delayed it forever in favour of fast wrong > way. > > So, the aim was: > > --- > NAME > modcfg - modify configuration > > SYNOPSIS > modcfg -f config_file -t config_type {-s param=val | -u param} > modcfg -l > modcfg -i plugin > > DESCRIPTION > The modcfg utility modifies configuration file in > accordance to parameters. > > The following options are available: > -f config_file- the file itself which to be modified > -t config_type- type of config_file. Type specifies the internal > structure of config_file, or, more roughly, > program which this file belongs to. To > list available types see -l option. > -s param=val - set configuration parameter 'param' to value > 'val'. > -u param - unset configuration parameter 'param' (or set it to > default). > > -l - list all supported types of config files. > > -i plugin- install plugin 'plugin' for modcfg utility. > Plugin is used to support additional configuration file > type. > > EXAMPLES > The command > modcfg -f /etc/rc.conf -t rc -s keymap=ru.cp1251 > sets parameter 'keymap' to value 'ru.cp1251'in file rc.conf. > > The command > modcfg -f /etc/rc.conf -t rc -u keymap > resets parameter 'keymap' to default value. I think it's great that you've taken on the task of finding a solution that works best for you, but this doesn't really work that well for the case of rc.conf(5) files because it neither sources `/etc/defaults/rc.conf' nor calls source_rc_confs() from said-file. So yes, one could modify a variable in a given file with your utility, but it doesn't take into account that rc.conf(5) is not a single file, it's a collection of files. Least of which contains: /etc/defaults/rc.conf /etc/rc.conf /etc/rc.conf.local /etc/rc.conf.d/* NOTE: The last one is not sourced by source_rc_confs() but is sourced by /etc/rc.d/* (the local-service boot-scripts), most [if not all] of which call load_rc_config(). In example, /etc/rc.d/foo would first source /etc/rc.subr then call `load_rc_config foo' which will both call source_rc_confs() from /etc/defaults/rc.conf AND source /etc/rc.conf.d/foo [if it exists]. This heirarchical structure forces a level of complexity onto the user which _can_ be confusing at times to less experienced users, and therefore providing a utility that ignores said-heirarchy forces the user to either navigate the complexity themselves or to write a wrapper script around your utility to manage it for them. Whereas, I started my utility (sysrc) from the ground-up with the express purpose of wrangling this complexity. I wanted a tool that would -- overall -- help me in my daily routines of managing thousands of FreeBSD workstations/pedestals/servers (fyi: a pedestal is server-class hardware in workstation-tower-like chassis). > To install obtained plugin 'samba.mcfg' use > modcfg -i samba.mcfg > After that configuration type 'samba' will be supported. Out of curiosity, why must the user be forced to "install the plugin" manually? Why not have the code automatically probe for the plugin on first-use? For example, when 'samba'-type is used for the first time, take that as a queue to load the module and if the module can't be loaded, die with an error. I think this streamlines the process (but wouldn't go as far as to remove the `-i' parameter -- keep it, it could be useful to some). > > --- > > INTERNALLY > > modcfg itself is very simple. It parse command line options, then load > plugin (module) for specified 'config_type', then call _set(file,param, > value) or _unset(file,param) function from this module. > So, plugin (module) should have functions such as: > _set(file, param, value) or, better name, {$type}_set. rc_set, for > example. > _unset(file, param) > _description - for display in module list. Your utility I think loosely resembles Apple's Core Data Programming API. I recently have been making my way through this Mac/iOS API known as "Core Data Programming" which uses relationship mapping (similar to your `config_type') to teach the Core Data API how modify different underlying data containers (but extends far beyond BSD-style configuration files). For example, Core Data -- in an object-oriented fashion -- provides a set of high-level access routines for accessing your data meanwhile the specifics of how that data was obtained or how said data is persistently stored back to the container are hidden from your application (much in the way that your utility masks from the user how the data is stored in the specific configuration-file type). Much like your utility, Core Data already supports some well-known data containers -- SQLite, Boulder/IO (simple key=value
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Sat, Oct 09, 2010 at 03:39:44PM -0700, Devin Teske wrote: > On Oct 9, 2010, at 1:25 PM, Garrett Cooper wrote: [...] > The second usage (": function") aids in finding the function > declaration among the usages. See, in Perl, I can simply search for > "sub" preceding the function name. In C, I tend to split the return > type from the function name and ensure that the function name always > starts in column-1 so I can search for "^funcname" to go to the > declaration opposed to the usages/references. In BASH, `function' is a > valid keyword and you can say "function funcname ( ) BLOCK" but > unfortunately in good ol' bourne shell, "function" is not an > understood keyword, ... but really liking this keyword, I decided to > make use of it in bourne shell by-way-of simply making it a > non-executed-expression (preceded it with ":" and terminated it with > ";"). I think function f() { ... } is a despicable bashism. In POSIX, an empty pair of parentheses is an unambiguous indication of a function definition; although FreeBSD sh also accepts () as a subshell containing an empty command, there is no reason to use that. In ksh, function f { ... } is different from f() { ... }, so there is a reason to use it, and function f() { ... } does not exist. > I originally had been programming in tests for '!' and 'in', but in > POSIX bourne-shell, they aren't defined (though understood) in the > keyword table (so type(1) balks in bourne-shell while csh and bash do > respond to '!' and 'in' queries). > Since you've pointed out command(1)... I now have a way of checking > '!'. Though unfortunately, "command -v", like type(1), also does not > like "in" (in bourne-shell at least). The type builtin in the original Bourne shell does not know keywords. The type builtin in FreeBSD sh knows them, but unlike most shells "in" is not a keyword -- it is only recognized at the appropriate places in a case or for command (this is probably a POSIX violation and may change in the future). > > "x$fmt" != x ? It seems like it could be simplified to: > > if [ $# -gt 0 ] > > then > >local fmt=$1 > >shift 1 > >eprintf "$fmt\n" "$@" > > fi > > I never understood why people don't trust the tools they are using... > > `[' is very very similar (if not identical) to test(1) > > [ "..." ] is the same thing as [ -n "..." ] or test -n "..." > [ ! "..." ] is the same things as [ -z "..." ] or test -z "..." > > I'll never understand why people have to throw an extra letter in there and > then compare it to that letter. > > If the variable expands to nothing, go ahead and let it. I've traced > every possible expansion of variables when used in the following > manner: > [ "$VAR" ] ... > and it never fails. If $VAR is anything but null, the entire > expression will evaluate to true. Right, except in very old implementations if VAR is -t, but those should be extinct and are not worth coding for. However, in some fairly recent implementations [ "$A" = "$B" ] does not work as expected for all values of A and B. For example, FreeBSD 7.0 returns true for A='(' and B=')' because it applies the POSIX rules in the wrong order (certainly, [ '(' "$X" ')' ] is true for most non-empty values of X, but this does not apply if X is an operator). > >> # depend $name [ $dependency ... ] > >> # > >> # Add a dependency. Die with error if dependency is not met. > >> # > >> : dependency checks performed after depend-function declaration > >> : function ; depend ( ) # $name [ $dependency ... ] > >> { > >>local by="$1" arg > >>shift 1 > >> > >>for arg in "$@"; do > >>local d > > Wouldn't it be better to declare this outside of the loop (I'm not > > sure how optimal it is to place it inside the loop)? > I'm assuming you mean the "local d" statement. There's no restriction > that says you have to put your variable declarations at the beginning > of a block (like in C -- even if only within a superficial block { in > the middle of nowhere } ... like that). > Meanwhile, in Perl, it's quite a difference to scope it to the loop > rather than the block. So, it all depends on whichever _looks_ nicer > to you ^_^ Although this works, I do not recommend it. It makes the impression that the variable is scoped to the do block, which is not the case as there is only function scope. Also, FreeBSD sh will register another local variable record if you make the same variable local again (but it will reset the variable to the correct value later). > > I'd say that you have bigger fish to try if your shell lacks the > > needed lexicon to parse built-ins like for, do, local, etc :)... local might be worth checking for as the original Bourne shell and ksh93 don't know it. -- Jilles Tjoelker ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On 10/07/2010 05:19 AM, Douglas K. Rand wrote: I think that this script might also fill a void with using Puppet as a configuration tool. Currently Puppet, as its default behaviour, uses files in /etc/rc.conf.d to set variables. This is no longer the case. Current versions edit /etc/rc.conf. -- Russell A Jackson Network Analyst California State University, Bakersfield ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On 10/8/2010 7:12 AM, Daniel Gerzo wrote: On 7.10.2010 15:42, Warren Block wrote: Consider also the docs that tell the user to echo 'something_enable="YES"' >> /etc/rc.conf which can produce duplicate and possibly differing entries. Or non-working entries if there was no ending \n present, or even a broken like forgetting to add two '>' and not having a backup :) rc.conf that breaks startup. You cannot program around stupidity. :) -- Breadth of IT experience, and| Nothin' ever doesn't change, depth of knowledge in the DNS. | but nothin' changes much. Yours for the right price. :) | -- OK Go http://SupersetSolutions.com/ ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Oct 10, 2010, at 5:15 PM, Garrett Cooper wrote: > On Sun, Oct 10, 2010 at 3:49 PM, Devin Teske wrote: > >> Hmmm, sysctl(9) is lock-free, which might imply that both sysctl(8) and >> sysctl(3) are also lock-free, and proposed sysrc(8) is lock-free, so might >> that imply that the atomicity tests would fare the same for all of the >> above? > > .../sys/kern/kern_sysctl.c says otherwise (look for the comment above > the sysctllock declaration). The locking is just hidden from the > developer/end-user. > >> Here's what I'm thinking we should do to solve this... >> Since the atomicity of the write operation is anything-but singular >> (meaning, it takes incrementally larger blocks of time to write larger >> amounts of data, increasing the risk-curve for failure to occur by two >> operations coinciding at the same time -- I'm truly sorry, my wife has me >> helping her with her business statistics II course, forgive me, I'll >> clarify). > > ... > > I think I said it before, but yes.. I completely agree with the > atomicity approach. I prefer `mktemp /tmp/XX' because it would do > nothing more than potentially clutter up /tmp if the operation fails > for whatever reason (instead of /etc), and it's less of a security > concern. I suppose that's less of a problem though, because if someone > has the ability to write to /etc, then all bets are off, but the > clutter part is a bit annoying.. I checked out mktemp(1)... just what the doctor ordered for preventing race-conditions. And it's in the base FreeBSD distribution even back as far as FreeBSD-4.11 (likely much further; but that's what I checked). > ... > > I would just hold to this statement in /etc/defaults/rc.conf: > > # All arguments must be in double or single quotes. > > and also state: > > "this tool functions based on the idea that the rc.conf files are > simply written, and can be evaluated as standalone configuration data. > Anything that doesn't conform to these requirements isn't guaranteed > to work with the tool in all cases" Simpler is indeed better ^_^ > > Thanks! > -Garrett > ___ > freebsd-hackers@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers > To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org" -- 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.te...@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 <- ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
Devin Teske writes: >>> GLOBALS >>> >>> # Global exit status variables >>> : ${SUCCESS:=0} >>> : ${FAILURE:=1} >> >> Should this really be set to something other than 0 or 1 by the >> end-user's environment? This would simplify a lot of return/exit >> calls... > > A scenario that I envision that almost never arises, but... > > Say someone wanted to call my script but wanted to mask it to always return > with success (why? I dunno... it's conceivable though). > > Example: (this should be considered ugly -- because it is) > > FAILURE=0 && sysrc foo && reboot Wouldn't this bork functions used inside a conditional? : ${FAILURE:=1} foo() { return ${FAILURE-1}; } if ! foo; then echo good else echo error fi $ test.sh good $ FAILURE=0 test.sh error I think only sysrc_set() is affected, though. if sysrc_set "$NAME" "${1#*=}"; then echo " -> $( sysrc "$NAME" )" fi $ sysrc hostname=blah hostname: raphael.local sysrc: cannot create /etc/rc.conf: permission denied $ FAILURE=0 sh sysrc hostname=blah hostname: raphael.local sysrc: cannot create /etc/rc.conf: permission denied -> raphael.local ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On 10/10/10 8:46 PM, Devin Teske wrote: On Oct 10, 2010, at 4:51 PM, Garance A Drosihn mailto:dro...@rpi.edu>> wrote: The latter does not cause an error. Try it: # [ "-n" = x ] ; echo $? 1 # [ -e = "no" ] ; echo $? 1 # [ -e = -n ] ; echo $? 1 1 is error. 0 is success. -- Um, yes, true. I know that. What I'm saying is that the command works as you'd want it to work. It does not hit a parsing error. The double-quotes did not change how the command behaved. You deleted the context of what I was replying to when I said the above. Looking at the examples I gave there, it probably would have been clearer if I had typed the exact same command with and without the double-quotes. Eg: On 10/10/10 7:09 PM, Devin Teske wrote: > However, enclosing the argument (as the 'x$foo' > portion is really just the first argument to the > '[' built-in) in quotes: > > [ "$foo" = x ] > > makes it so that the expansion is taken as: > > [ "-n" = x ] > > rather than: > > [ -n = x ] > > The former not causing an error, while the latter does. Your second example does not cause an error. Try it: # [ "-n" = "-n" ] ; echo $? 0 # [ "-n" = x ] ; echo $? 1 Compared to the double-quote-less: # [ -n = "-n" ] ; echo $? 0 # [ -n = x ] ; echo $? 1 -- Garance ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On 10/10/10 7:09 PM, Devin Teske wrote: On Oct 9, 2010, at 10:25 PM, Julian Elischer wrote: For what it matters, I'v enever found the [ "x$foo" = "x" ] construct to be useful. the quoting seems to work for everything I've ever worked on. There have been times where I had scripts which could get errors unless "x$foo" was used, but it's been more than 10 years since I last hit that situation. Of course, ever since I did hit it, I tend to write my 'test' parameters in ways which avoid the problem. It might have only been when checking if the variable was set to anything. Eg, using: if [ "$foo" ] ; then instead of: if [ -n "$foo" ] ; then ... Or it might have been when combining multiple checks in a single 'test' (using -a's, etc). However, I'm not going to try to dream up a pathological example of that right now. I agree... I think that the "x" syntax came around for when people were using non-quoted syntax... for example... [ x$foo = x ] is still very useful in that it prevents the error when $foo expands to "-e". The non-quoted example is dangerous in the case where $foo has multiple words in it. The "x" does not save you from that problem. I have a 'list_args' script which just lists out the parameters it is called with: # Test="this is a multi-word test" # list_args x$Test list_args at 19:22:27 Oct 10: $# = 5 ARG[000] l=005: 'xthis' ARG[001] l=002: 'is' ARG[002] l=001: 'a' ARG[003] l=010: 'multi-word' ARG[004] l=004: 'test' However, enclosing the argument (as the 'x$foo' portion is really just the first argument to the '[' built-in) in quotes: [ "$foo" = x ] makes it so that the expansion is taken as: [ "-n" = x ] rather than: [ -n = x ] The former not causing an error, while the latter does. The latter does not cause an error. Try it: # [ "-n" = x ] ; echo $? 1 # [ -e = "no" ] ; echo $? 1 # [ -e = -n ] ; echo $? 1 Quite functionally, at a C-level, if you have your array, ... argv[0] = "[\0"; argv[1] = "\"-n\"\0"; /* quoted syntax */ argv[2] = "=\0"; argv[3] = "x\0"; and argv[0] = "[\0"; argv[1] = "-n\0"; /* non-quoted syntax */ argv[2] = "=\0"; argv[3] = "x\0"; You won't see the double-quotes in the C program. The shell processes single and double quotes, and passes the result to the C program which is running. It might be different for built-in functions, but /bin/test would never see the double-quotes if they were used. And since the built-in function has to work the same as standalone function, I doubt the built-in would be any different. # list_args "-n" list_args at 19:36:15 Oct 10: $# = 1 ARG[000] l=002: '-n' # list_args -n list_args at 19:36:22 Oct 10: $# = 1 ARG[000] l=002: '-n' (note that the single-quotes you see there are printed by the list_args script itself for display purposes). /disclaimer: I think this is the first post that I've made with the new "open-source edition" of Eudora, and I have no idea if this will be formatted the way I'm expecting it be!/ -- Garance Alistair Drosehn = dro...@rpi.edu Senior Systems Programmer or g...@freebsd.org Rensselaer Polytechnic Institute; Troy, NY; USA ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Oct 10, 2010, at 4:51 PM, Garance A Drosihn wrote: > The latter does not cause an error. Try it: > > # [ "-n" = x ] ; echo $? > 1 > > # [ -e = "no" ] ; echo $? > 1 > > # [ -e = -n ] ; echo $? > 1 1 is error. 0 is success. -- Devin ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Oct 10, 2010, at 4:51 PM, Garance A Drosihn wrote: > On 10/10/10 7:09 PM, Devin Teske wrote: >> However, enclosing the argument (as the 'x$foo' portion is really just the >> first argument to the '[' built-in) in quotes: >> >> [ "$foo" = x ] >> >> makes it so that the expansion is taken as: >> >> [ "-n" = x ] >> >> rather than: >> >> [ -n = x ] >> >> The former not causing an error, while the latter does. >> > The latter does not cause an error. Try it: > > # [ "-n" = x ] ; echo $? > 1 > > # [ -e = "no" ] ; echo $? > 1 > > # [ -e = -n ] ; echo $? > 1 Logical error, not functional error. >> Quite functionally, at a C-level, if you have your array, ... >> >> argv[0] = "[\0"; >> argv[1] = "\"-n\"\0"; /* quoted syntax */ >> argv[2] = "=\0"; >> argv[3] = "x\0"; >> >> and >> >> argv[0] = "[\0"; >> argv[1] = "-n\0"; /* non-quoted syntax */ >> argv[2] = "=\0"; >> argv[3] = "x\0"; >> >> > You won't see the double-quotes in the C program. Correct, an external C programming will get the arguments just like a shell script. > The shell processes single and double quotes, and passes the result to the > C program which is running. It might be different for built-in functions, Indeed it is. > but /bin/test would never see the double-quotes if they were used. And since > the built-in function has to work the same as standalone function There is no distinction between "built-in function" and "standalone function". I think you mean "built-in" versus "external binary". The way that parameters are passed off to the internal parser is different than the way arguments are passed to external executables. > , I doubt the built-in would be any different. > > # list_args "-n" > > list_args at 19:36:15 Oct 10: $# = 1 > ARG[000] l=002: '-n' > # list_args -n > > list_args at 19:36:22 Oct 10: $# = 1 > ARG[000] l=002: '-n' > > (note that the single-quotes you see there are printed by the list_args > script itself for display purposes). > > disclaimer: I think this is the first post that I've made with the new > "open-source edition" of Eudora, and I have no idea if this will be formatted > the way I'm expecting it be! > > -- > Garance Alistair Drosehn = dro...@rpi.edu > Senior Systems Programmer or g...@freebsd.org > Rensselaer Polytechnic Institute; Troy, NY; USA > -- 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.te...@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 <- ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Sun, Oct 10, 2010 at 3:49 PM, Devin Teske wrote: > Trimming further context... > On Oct 9, 2010, at 7:30 PM, Garrett Cooper wrote: ... > Perhaps you meant env FAILURE=0 sysrc foo && reboot ? > > $ cat failure.sh > #!/bin/sh > echo "FAILURE: $FAILURE" > $ FAILURE=0 && sh failure.sh > FAILURE: > $ env FAILURE=0 sh failure.sh > FAILURE: 0 > > Ah, beautiful. I'd been searching for a way to set an environment variable > prior to running a command in one-swift blow. I see env(1) is handy for > that. And the cool thing is that it works from other shells: $ export FOO=0; csh -c "env FOO=1 csh -c 'env | grep FOO'" FOO=1 That's why I prefer it in command line examples (it's deterministic). > Though honestly, the reason it's not working for you is because FAILURE has > not been exported... I didn't state it explicitly that way, but yes... that's what I was implying. ... > Hence why when adding environment-variable based tunables in ~/.bashrc, it's > best to use export (either after initial assignment or with assignment > specified on export line in-one-go) else the assignment won't survive the > script... Which makes sense because you're the developer, but does it make sense for production quality code, especially when users are better than developers at finding code flaws, i.e. doing the following: $ export FAILURE=a $ exit $FAILURE exit: Illegal number: a $ echo $? 2 Implementation in the shell may vary (again, this was /bin/sh). > Safe for four exceptions... > 1. When the script itself executes the set(1) built-in with either `-a' flag > or `-o allexport' arguments > 2. The parent shell does the above and does not execute the child as a > sub-shell but rather sources the child using the `.' built-in > 3. The script itself has an invocation line resembling any of the following: > #!/bin/sh -a > #!/bin/sh -o allexport > #!/usr/bin/env sh -a > #!/usr/bin/env sh -o allexport Hmm... forgot about that :D. > 4. The parent shell does the above and does not execute the child as a > sub-shell but rather sources the child using the `.' built-in. > Which, in any of the above cases, simple assignment to a variable name will > cause it to be exported to all children/sub-shell environments. > Works for example in a live-shell too... > $ unset FAILURE > # start from a clean slate > $ FAILURE=0 && sh failure.sh > FAILURE: > # Success, we're not exporting on bare assignment > $ set -a > # Turn on allexport in the interactive shell > $ FAILURE=0 && sh failure.sh > FAILURE: 0 > # Success, we're exporting on bare-assignment due to allexport > $ set +a > # Turn off allexport in the interactive shell > $ FAILURE=0 && sh failure.sh > FAILURE: 0 > # It was still exported > $ unset FAILURE > # Let's unexport it > $ FAILURE=0 && sh failure.sh > FAILURE: > # success, no longer exported automatically via allexport feature Part of the reason why I follow the set global once with empty values or defaults and declare locals given the chance and if I care. Otherwise there's too much wiggle room for surprises from the user's environment :). > Understood. There really isn't any degree of shell style in FreeBSD, > but it would be nice if there was.. > > I find that to be the case quite often when dealing with shell scripting. > I've been trying to bring a little style to the shell scripting world these > days ^_^ > > > Ah, coolness. command(1) is new to me just now ^_^ > > Yeah.. I was looking for something 100% portable after I ran into > issues with writing scripts for Solaris :). > > I went back to our legacy systems just now (FreeBSD-4.11) and tried this... > $ uname -spr > FreeBSD 4.11-STABLE i386 > $ /bin/sh -c "command -v '['" > command: unknown option: -v > Meanwhile: > $ uname -spr > FreeBSD 8.1-RELEASE-p1 amd64 > $ /bin/sh -c "command -v '['" > [ > So it would appear that on FreeBSD at least, type(1) built-in is more > portable (this perhaps traces back to it's 4.4BSDLite roots). > I was thinking ... perhaps another flag. But alas, -p was the only valid > option back then, which only causes a default PATH to be used rather than an > inherited one. Potentially. command(1) is just POSIX compatible, whereas type may be BSD compatible *shrugs*. ... > On legacy system: > $ uname -spr > FreeBSD 4.11-STABLE i386 > $ /bin/sh -c '[ "-n" ] && echo true' > true > $ /bin/sh -c '[ "-e" ] && echo true' > true > $ /bin/sh -c '[ "-z" ] && echo true' > true > $ /bin/sh -c '[ "-r" ] && echo true' > true > $ /bin/sh -c '[ "-f" ] && echo true' > true > $ /bin/sh -c '[ "-s" ] && echo true' > true > Up-to-date is the same: > $ uname -spr > FreeBSD 8.1-RELEASE-p1 amd64 > $ /bin/sh -c '[ "-n" ] && echo true' > true > $ /bin/sh -c '[ "-e" ] && echo true' > true > $ /bin/sh -c '[ "-z" ] && echo true' > true > $ /bin/sh -c '[ "-r" ] && echo true' > true > $ /bin/sh -c '[ "-f" ] && echo true' > true > $ /bin/sh -c '[ "-s" ] && echo true' > true Fair enough. My supposed knowledge and/or memory mislead me here :/. ... > and the `our' keyword
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Oct 9, 2010, at 10:25 PM, Julian Elischer wrote: > Ah grasshoppers... > > /me wonders if anyone will get the full significance of that.. > > > On 10/9/10 3:39 PM, Devin Teske wrote: >> On Oct 9, 2010, at 1:25 PM, Garrett Cooper wrote: >> >> >>> Why not just do... >>> >>> if [ "x$rc_conf_files" = x -o "x$varname" = x ] >>> then >>>return ${FAILURE-1} >>> fi >> I think you'll find (quite pleasantly) that if you intonate the lines... >> >> "rc_conf_files [is non-null] OR return failure" >> "varname [is non-null] OR return failure" >> >> Sounds a lot better/cleaner than the intonation of the suggested replacement: >> >> "if x plus rc_conf_files expands to something that is not equal to x OR >> x plus the expansion of varname is not x then return failure" >> > > > For what it matters, I'v enever found the [ "x$foo" = "x" ] construct to be > useful. > the quoting seems to work for everything I've ever worked on. I agree... I think that the "x" syntax came around for when people were using non-quoted syntax... for example... [ x$foo = x ] is still very useful in that it prevents the error when $foo expands to "-e". However, enclosing the argument (as the 'x$foo' portion is really just the first argument to the '[' built-in) in quotes: [ "$foo" = x ] makes it so that the expansion is taken as: [ "-n" = x ] rather than: [ -n = x ] The former not causing an error, while the latter does. Quite functionally, at a C-level, if you have your array, ... argv[0] = "[\0"; argv[1] = "\"-n\"\0"; /* quoted syntax */ argv[2] = "=\0"; argv[3] = "x\0"; and argv[0] = "[\0"; argv[1] = "-n\0"; /* non-quoted syntax */ argv[2] = "=\0"; argv[3] = "x\0"; The C-code that switch'es on the argv element can tell the difference between a leading quote and a leading dash and does indeed do the right thing for all expansions of the variable within a double-quote block ("..."). Though, the non-quoted syntax should be avoided at all costs, imho unless you know for a fact that the expansion of the variable will never include a character from $IFS (defaults to space, tab, newline). If it does, then it'll evaluate to a new positional argument for the C-code. Take the following example: $ foo="abc = abc" $ [ $foo ] && echo true true $ foo="abc = 123" $ [ $foo ] && echo true # no output (not true) Whereas the quoted syntax: $ [ "$foo" ] will always evaluate to true because there is an implied "-n" operator for the case where the first-and-last positional argument is a double-quoted string, and... $ [ -n "$foo" ] always evaluates to true in the above cases for foo ("abc = abc" then later "abc = 123"). > ... > > Now One thing that should be bourne in mind (heh) is that > as there is a 'usual' form of format for perl there is one for sh as well so > it's not "polite" > to make one's sh code look like perl. :-) Perusing sh(1) today... found examples of the lazy operators: [ expr ] || expr [ expr ] && expr Search under "Short-Circuit List Operators" I'd say that the description therein is a green-light to treat sh like perl ^_^ > ___ > freebsd-hackers@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers > To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org" -- 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.te...@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 <- ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
Trimming further context... On Oct 9, 2010, at 7:30 PM, Garrett Cooper wrote: > Trimming out some context... > > On Sat, Oct 9, 2010 at 3:39 PM, Devin Teske wrote: >> > > ... > > Perhaps you meant env FAILURE=0 sysrc foo && reboot ? > > $ cat failure.sh > #!/bin/sh > echo "FAILURE: $FAILURE" > $ FAILURE=0 && sh failure.sh > FAILURE: > $ env FAILURE=0 sh failure.sh > FAILURE: 0 Ah, beautiful. I'd been searching for a way to set an environment variable prior to running a command in one-swift blow. I see env(1) is handy for that. Though honestly, the reason it's not working for you is because FAILURE has not been exported... $ while read LINE; do echo "$LINE" >> failure.sh; done #!/bin/sh echo "FAILURE: $FAILURE" ^D ### nifty way to create a file ^_^ $ cat failure.sh #!/bin/sh echo "FAILURE: $FAILURE" ### Yup, that's what we wrote to it. $ unset FAILURE ### Let's start clean $ FAILURE=0 && sh failure.sh FAILURE: ### No effect... (cause it's not exported yet) $ export FAILURE ### Should have an effect now, let's try $ FAILURE=0 && sh failure.sh FAILURE: 0 ### Success ... once it has been exported by name (with a value or not) it is always exported $ FAILURE=1 && sh failure.sh FAILURE: 1 ### no need to re-export, once exported by-name, new assignments are exported $ unset FAILURE ### Only way to get it to be unexported once exported $ FAILURE=0 && sh failure.sh FAILURE: ### Assignment no longer exported to sub-shells So, I guess an alternative to the usage of env(1) would be: export FAILURE=0 && sh failure.sh Works as expected... $ unset FAILURE $ export FAILURE=0 && sh failure.sh FAILURE: 0 Hence why when adding environment-variable based tunables in ~/.bashrc, it's best to use export (either after initial assignment or with assignment specified on export line in-one-go) else the assignment won't survive the script... Safe for four exceptions... 1. When the script itself executes the set(1) built-in with either `-a' flag or `-o allexport' arguments 2. The parent shell does the above and does not execute the child as a sub-shell but rather sources the child using the `.' built-in 3. The script itself has an invocation line resembling any of the following: #!/bin/sh -a #!/bin/sh -o allexport #!/usr/bin/env sh -a #!/usr/bin/env sh -o allexport 4. The parent shell does the above and does not execute the child as a sub-shell but rather sources the child using the `.' built-in. Which, in any of the above cases, simple assignment to a variable name will cause it to be exported to all children/sub-shell environments. Works for example in a live-shell too... $ unset FAILURE # start from a clean slate $ FAILURE=0 && sh failure.sh FAILURE: # Success, we're not exporting on bare assignment $ set -a # Turn on allexport in the interactive shell $ FAILURE=0 && sh failure.sh FAILURE: 0 # Success, we're exporting on bare-assignment due to allexport $ set +a # Turn off allexport in the interactive shell $ FAILURE=0 && sh failure.sh FAILURE: 0 # It was still exported $ unset FAILURE # Let's unexport it $ FAILURE=0 && sh failure.sh FAILURE: # success, no longer exported automatically via allexport feature > Understood. There really isn't any degree of shell style in FreeBSD, > but it would be nice if there was.. I find that to be the case quite often when dealing with shell scripting. I've been trying to bring a little style to the shell scripting world these days ^_^ >> Ah, coolness. command(1) is new to me just now ^_^ > > Yeah.. I was looking for something 100% portable after I ran into > issues with writing scripts for Solaris :). I went back to our legacy systems just now (FreeBSD-4.11) and tried this... $ uname -spr FreeBSD 4.11-STABLE i386 $ /bin/sh -c "command -v '['" command: unknown option: -v Meanwhile: $ uname -spr FreeBSD 8.1-RELEASE-p1 amd64 $ /bin/sh -c "command -v '['" [ So it would appear that on FreeBSD at least, type(1) built-in is more portable (this perhaps traces back to it's 4.4BSDLite roots). I was thinking ... perhaps another flag. But alas, -p was the only valid option back then, which only causes a default PATH to be used rather than an inherited one. > ... > >> If the variable expands to nothing, go ahead and let it. I've traced every >> possible expansion of variables when used in the following manner: >> [ "$VAR" ] ... >> and it never fails. If $VAR is anything but null, the entire expression will >> evaluate to true. >> Again... coming from 15+ years of perl has made my eyes read the following >> block of code: >> if [ "$the_network_is_enabled" ]; then >> aloud in my head as "if the network is enabled, then ..." (not too far of a >> stretch)... which has a sort of quintessential humanized logic to it, don't >> you think? >> Now, contrast that with this block: >> if [ "x$the_network_is_enabled" = x ]; then >> (one might verbalize that in their head as "if x plus `the network is >> enable
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
> On 10/9/10 7:30 PM, Garrett Cooper wrote: > > > >> [ "..." ] is the same thing as [ -n "..." ] or test -n "..." > >> [ ! "..." ] is the same things as [ -z "..." ] or test -z "..." > >> I'll never understand why people have to throw an extra letter in there and > >> then compare it to that letter. > > I ran into issues using ! on Solaris ksh recently (not using test), > > and I agree that your example below is more straightforward and > > readable than the other examples I've dealt with in the past. > > > Ah that reminds me for the reason for "X$foo" = "X" but grasshopper, in Version 6 there was no test(1), hence the x$1 = x > > it's in case $foo evaluates to "-n" or similar... > > It's been a long time... but these days a data misevaluation leads to > such things ad SQL injection attacks > and I see no reason that a shell injection attack shouldn't be possible. ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On 10/9/10 7:30 PM, Garrett Cooper wrote: [ "..." ] is the same thing as [ -n "..." ] or test -n "..." [ ! "..." ] is the same things as [ -z "..." ] or test -z "..." I'll never understand why people have to throw an extra letter in there and then compare it to that letter. I ran into issues using ! on Solaris ksh recently (not using test), and I agree that your example below is more straightforward and readable than the other examples I've dealt with in the past. Ah that reminds me for the reason for "X$foo" = "X" it's in case $foo evaluates to "-n" or similar... It's been a long time... but these days a data misevaluation leads to such things ad SQL injection attacks and I see no reason that a shell injection attack shouldn't be possible. ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
Ah grasshoppers... /me wonders if anyone will get the full significance of that.. On 10/9/10 3:39 PM, Devin Teske wrote: On Oct 9, 2010, at 1:25 PM, Garrett Cooper wrote: Why not just do... if [ "x$rc_conf_files" = x -o "x$varname" = x ] then return ${FAILURE-1} fi I think you'll find (quite pleasantly) that if you intonate the lines... "rc_conf_files [is non-null] OR return failure" "varname [is non-null] OR return failure" Sounds a lot better/cleaner than the intonation of the suggested replacement: "if x plus rc_conf_files expands to something that is not equal to x OR x plus the expansion of varname is not x then return failure" For what it matters, I'v enever found the [ "x$foo" = "x" ] construct to be useful. the quoting seems to work for everything I've ever worked on. so "officially" I'd express it as: if [ -n "$rc_conf_files" -o -n "$varname" ] but if I were hacking I'd probably express it as if [ "$rc_conf_files" != "" ] || [ "$varname" != "" ] then . I also sometimes find the use of the (()) operator to be useful. Now One thing that should be bourne in mind (heh) is that as there is a 'usual' form of format for perl there is one for sh as well so it's not "polite" to make one's sh code look like perl. :-) ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
Trimming out some context... On Sat, Oct 9, 2010 at 3:39 PM, Devin Teske wrote: > ... > Should this really be set to something other than 0 or 1 by the > end-user's environment? This would simplify a lot of return/exit > calls... > > A scenario that I envision that almost never arises, but... > Say someone wanted to call my script but wanted to mask it to always return > with success (why? I dunno... it's conceivable though). > Example: (this should be considered ugly -- because it is) > FAILURE=0 && sysrc foo && reboot But then someone could do sysrc foo || : && reboot, or more simply sysrc foo; reboot Perhaps you meant env FAILURE=0 sysrc foo && reboot ? $ cat failure.sh #!/bin/sh echo "FAILURE: $FAILURE" $ FAILURE=0 && sh failure.sh FAILURE: $ env FAILURE=0 sh failure.sh FAILURE: 0 > Efficacy: > The `reboot' rvalue of '&&' will always execute because FAILURE. > I don't really know why I got into the practice of writing scripts this > way... most likely a foregone conclusion that seemed like a good idea at one > time but never really amounted to anything substantive (in fact, it should > perhaps be considered heinous). > I agree... a productionized version in the base distribution should lack > such oddities. The script should do: > SUCCESS=0 > FAILURE=1 > and be done with it. > Though, I've been sometimes known to follow the habits of C-programming and > instead do: > EXIT_SUCCESS=0 > EXIT_FAILURE=1 > (real macros defined by system includes; though in C-land they aren't 0/1 > but rather 0/-1 IIRC) > I just found it redundant to say: > exit $EXIT_SUCCESS > and shorter/more-succinct to say: > exit $SUCCESS Understood :). I try to avoid sysexits just because bde@ wasn't too happy in a review that I posted some C code in a review. ... > I borrow my argument-documentation style from 15+ years of perl programming. > I think it's all just personal preference. Personally, I like to jam it all > one line specifically so that I can do a quick mark, then "?function.*name" > to jump up to the definition-line, "yy" (for yank-yank; copies current line > into buffer), then jump back to my mark, "p" for paste, then replace the > variables with what I intend to pass in for the particular call. > Using vi for years teaches interesting styles -- packing a list of keywords > onto a single line to grab/paste elsewhere are just one of those little > things you learn. Understood. There really isn't any degree of shell style in FreeBSD, but it would be nice if there was.. ... > The first ": dependency checks ..." is just a note to myself. I used ":" > syntax to make it stand-out differently than the "#" syntax. Not to mention > that when I go through my scripts (well, the ones that are intended for > functioning within an embedded environment at least) I expect to see a call > to "depend()" before a) each/every function and b) each/every large > contiguous block of code (or at least the blocks that look like they are > good candidates for re-use in other scripts). > The second usage (": function") aids in finding the function declaration > among the usages. See, in Perl, I can simply search for "sub" preceding the > function name. In C, I tend to split the return type from the function name > and ensure that the function name always starts in column-1 so I can search > for "^funcname" to go to the declaration opposed to the usages/references. > In BASH, `function' is a valid keyword and you can say "function funcname ( > ) BLOCK" but unfortunately in good ol' bourne shell, "function" is not an > understood keyword, ... but really liking this keyword, I decided to make > use of it in bourne shell by-way-of simply making it a > non-executed-expression (preceded it with ":" and terminated it with ";"). Yeah, that's one of the nicer readability points that would be helpful in POSIX. Unfortunately none of the other shell code in FreeBSD [that I've seen] is written that way, so it would look kind of out of place. But I understand your reasoning... > > { > > local fd=$1 > > [ $# -gt 1 ] || return ${FAILURE-1} > > While working at IronPort, Doug (my tech lead) has convinced me that > constructs like: > > if [ $# -le 1 ] > then > return ${FAILURE-1} > fi > > Never did understand why folks insisted on splitting the if/then syntax (or > while/do or for/do etc.) into multiple lines. I've always found that putting > the semi-colon in there made it easier to read. Well, I [personally] prefer the semi-colon, but I can see merits with the other format because spacing between the expressions, the semi-colon, etc is variable, so code gets inconsistent over time (looking back I've noticed that even my code has become inconsistent in that manner). Either way can easily be searched and extracted via sed or awk. > Are a little more consistent and easier to follow than: > > [ $# -gt 1 ] || return ${FAILURE-1} > > Because some folks have a tendency to chain shell expressions, i.e. > > I agree with you that any-more
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
Forgive me for this top posting but I don't want to risk ruining the perfect flow of Garret's analysis. I read through it as if I was in a classroom lecture. I have a special folder in kmail called "FreeBSD Tops" where I put mail that makes me discover something unknown to me about FBSD, and this one is marked as important. Thank you both, Devin and Garret!. -- Mario Lobo http://www.mallavoodoo.com.br FreeBSD since 2.2.8 [not Pro-Audio YET!!] (99% winfoes FREE) On Saturday 09 October 2010 17:25:55 Garrett Cooper wrote: > On Wed, Oct 6, 2010 at 8:29 PM, Devin Teske wrote: > > On Oct 6, 2010, at 4:09 PM, Brandon Gooch wrote: > >> On Wed, Oct 6, 2010 at 3:45 PM, Devin Teske wrote: > >>> Hello fellow freebsd-hackers, > >>> > >>> Long-time hacker, first-time poster. > >>> > >>> I'd like to share a shell script that I wrote for FreeBSD system > >>> administration. > >> > >> It seems the list ate the attachment :( > > > > Here she is ^_^ Comments welcome. > > Hah. More nuclear reactor than bikeshed :D! > > > #!/bin/sh > > # -*- tab-width: 4 -*- ;; Emacs > > # vi: set tabstop=4 :: Vi/ViM > > > > # > > # Default setting whether to dump a list of internal dependencies upon > > exit # > > > > : ${SYSRC_SHOW_DEPS:=0} > > > > GLOBALS > > > > # Global exit status variables > > > > : ${SUCCESS:=0} > > : ${FAILURE:=1} > > Should this really be set to something other than 0 or 1 by the > end-user's environment? This would simplify a lot of return/exit > calls... > > > # > > # Program name > > # > > progname="${0##*/}" > > > > # > > # Options > > # > > SHOW_EQUALS= > > SHOW_NAME=1 > > > > # Reserved for internal use > > _depend= > > When documenting arguments passed to functions, I usually do something > like: > > # 1 - a var > # 2 - another var > # > # ... etc > > because it's easier to follow for me at least. > > Various spots in the codebase have differing styles though (and it > would be better to follow the style in /etc/rc.subr, et all for > consistency, because this tool is a consumer of those APIs). > > > FUNCTION > > > > # fprintf $fd $fmt [ $opts ... ] > > # > > # Like printf, except allows you to print to a specific file-descriptor. > > Useful # for printing to stderr (fd=2) or some other known > > file-descriptor. # > > > > : dependency checks performed after depend-function declaration > > : function ; fprintf ( ) # $fd $fmt [ $opts ... ] > > Dumb question. Does declaring `: dependency checks performed after > depend-function declaration' and `: function' buy you anything other > than readability via comments with syntax checking? > > > { > >local fd=$1 > >[ $# -gt 1 ] || return ${FAILURE-1} > > While working at IronPort, Doug (my tech lead) has convinced me that > constructs like: > > if [ $# -le 1 ] > then > return ${FAILURE-1} > fi > > Are a little more consistent and easier to follow than: > > [ $# -gt 1 ] || return ${FAILURE-1} > > Because some folks have a tendency to chain shell expressions, i.e. > > expr1 || expr2 && expr3 > > Instead of: > > if expr1 || expr2 > then > expr3 > fi > > or... > > if ! expr1 > then > expr2 > fi > if [ $? -eq 0 ] > then > expr3 > fi > > I've caught myself chaining 3 expressions together, and I broke that > down into a simpler (but more longhand format), but I've caught people > chaining 4+ expressions together, which just becomes unmanageable to > follow (and sometimes bugs creep in because of operator ordering and > expression evaluation and subshells, etc, but that's another topic for > another time :)..). > > >shift 1 > >printf "$@" >&$fd > > } > > > > # eprintf $fmt [ $opts ... ] > > # > > # Print a message to stderr (fd=2). > > # > > > > : dependency checks performed after depend-function declaration > > : function ; eprintf ( ) # $fmt [ $opts ... ] > > > > { > >fprintf 2 "$@" > > } > > > > # show_deps > > # > > # Print the current list of dependencies. > > # > > > > : dependency checks performed after depend-function declaration > > : function ; show_deps ( ) # > > > > { > >if [ "$SYSRC_SHOW_DEPS" = "1" ]; then > >eprintf "Running internal dependency list:\n" > > > >local d > >for d in $_depend; do > >eprintf "\t%-15ss%s\n" "$d" "$( type "$d" )" > > The command(1) -v builtin is more portable than the type(1) builtin > for command existence lookups (it just doesn't tell you what the > particular item is that you're dealing with like type(1) does). > > I just learned that it also handles other builtin lexicon like if, > for, while, then, do, done, etc on FreeBSD at least; POSIX also > declares that it needs to support that though, so I think it's a safe > assumption to state that command -v will provide you with what you > need. > > >
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Oct 9, 2010, at 1:25 PM, Garrett Cooper wrote: > On Wed, Oct 6, 2010 at 8:29 PM, Devin Teske wrote: >> >> On Oct 6, 2010, at 4:09 PM, Brandon Gooch wrote: >> >>> On Wed, Oct 6, 2010 at 3:45 PM, Devin Teske wrote: Hello fellow freebsd-hackers, Long-time hacker, first-time poster. I'd like to share a shell script that I wrote for FreeBSD system administration. >>> >>> It seems the list ate the attachment :( >> >> >> Here she is ^_^ Comments welcome. > > Hah. More nuclear reactor than bikeshed :D! ^_^ You're about to find out more... > >> #!/bin/sh >> # -*- tab-width: 4 -*- ;; Emacs >> # vi: set tabstop=4 :: Vi/ViM > >> # >> # Default setting whether to dump a list of internal dependencies upon exit >> # >> : ${SYSRC_SHOW_DEPS:=0} >> >> GLOBALS >> >> # Global exit status variables >> : ${SUCCESS:=0} >> : ${FAILURE:=1} > > Should this really be set to something other than 0 or 1 by the > end-user's environment? This would simplify a lot of return/exit > calls... A scenario that I envision that almost never arises, but... Say someone wanted to call my script but wanted to mask it to always return with success (why? I dunno... it's conceivable though). Example: (this should be considered ugly -- because it is) FAILURE=0 && sysrc foo && reboot Efficacy: The `reboot' rvalue of '&&' will always execute because FAILURE. I don't really know why I got into the practice of writing scripts this way... most likely a foregone conclusion that seemed like a good idea at one time but never really amounted to anything substantive (in fact, it should perhaps be considered heinous). I agree... a productionized version in the base distribution should lack such oddities. The script should do: SUCCESS=0 FAILURE=1 and be done with it. Though, I've been sometimes known to follow the habits of C-programming and instead do: EXIT_SUCCESS=0 EXIT_FAILURE=1 (real macros defined by system includes; though in C-land they aren't 0/1 but rather 0/-1 IIRC) I just found it redundant to say: exit $EXIT_SUCCESS and shorter/more-succinct to say: exit $SUCCESS >> # >> # Program name >> # >> progname="${0##*/}" >> >> # >> # Options >> # >> SHOW_EQUALS= >> SHOW_NAME=1 >> >> # Reserved for internal use >> _depend= > > When documenting arguments passed to functions, I usually do something like: > > # 1 - a var > # 2 - another var > # > # ... etc > > because it's easier to follow for me at least. > > Various spots in the codebase have differing styles though (and it > would be better to follow the style in /etc/rc.subr, et all for > consistency, because this tool is a consumer of those APIs). I borrow my argument-documentation style from 15+ years of perl programming. I think it's all just personal preference. Personally, I like to jam it all one line specifically so that I can do a quick mark, then "?function.*name" to jump up to the definition-line, "yy" (for yank-yank; copies current line into buffer), then jump back to my mark, "p" for paste, then replace the variables with what I intend to pass in for the particular call. Using vi for years teaches interesting styles -- packing a list of keywords onto a single line to grab/paste elsewhere are just one of those little things you learn. >> FUNCTION >> >> # fprintf $fd $fmt [ $opts ... ] >> # >> # Like printf, except allows you to print to a specific file-descriptor. >> Useful >> # for printing to stderr (fd=2) or some other known file-descriptor. >> # >> : dependency checks performed after depend-function declaration >> : function ; fprintf ( ) # $fd $fmt [ $opts ... ] > > Dumb question. Does declaring `: dependency checks performed after > depend-function declaration' and `: function' buy you anything other > than readability via comments with syntax checking? The first ": dependency checks ..." is just a note to myself. I used ":" syntax to make it stand-out differently than the "#" syntax. Not to mention that when I go through my scripts (well, the ones that are intended for functioning within an embedded environment at least) I expect to see a call to "depend()" before a) each/every function and b) each/every large contiguous block of code (or at least the blocks that look like they are good candidates for re-use in other scripts). The second usage (": function") aids in finding the function declaration among the usages. See, in Perl, I can simply search for "sub" preceding the function name. In C, I tend to split the return type from the function name and ensure that the function name always starts in column-1 so I can search for "^funcname" to go to the declaration opposed to the usages/references. In BASH, `function' is a valid keyword and you can say "function funcname ( ) BLOCK" but unfortunately in good ol' bourne shell, "function" is not an understoo
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Wed, Oct 6, 2010 at 8:29 PM, Devin Teske wrote: > > On Oct 6, 2010, at 4:09 PM, Brandon Gooch wrote: > >> On Wed, Oct 6, 2010 at 3:45 PM, Devin Teske wrote: >>> Hello fellow freebsd-hackers, >>> >>> Long-time hacker, first-time poster. >>> >>> I'd like to share a shell script that I wrote for FreeBSD system >>> administration. >>> >> >> It seems the list ate the attachment :( > > > Here she is ^_^ Comments welcome. Hah. More nuclear reactor than bikeshed :D! > #!/bin/sh > # -*- tab-width: 4 -*- ;; Emacs > # vi: set tabstop=4 :: Vi/ViM > # > # Default setting whether to dump a list of internal dependencies upon exit > # > : ${SYSRC_SHOW_DEPS:=0} > > GLOBALS > > # Global exit status variables > : ${SUCCESS:=0} > : ${FAILURE:=1} Should this really be set to something other than 0 or 1 by the end-user's environment? This would simplify a lot of return/exit calls... > # > # Program name > # > progname="${0##*/}" > > # > # Options > # > SHOW_EQUALS= > SHOW_NAME=1 > > # Reserved for internal use > _depend= When documenting arguments passed to functions, I usually do something like: # 1 - a var # 2 - another var # # ... etc because it's easier to follow for me at least. Various spots in the codebase have differing styles though (and it would be better to follow the style in /etc/rc.subr, et all for consistency, because this tool is a consumer of those APIs). > FUNCTION > > # fprintf $fd $fmt [ $opts ... ] > # > # Like printf, except allows you to print to a specific file-descriptor. > Useful > # for printing to stderr (fd=2) or some other known file-descriptor. > # > : dependency checks performed after depend-function declaration > : function ; fprintf ( ) # $fd $fmt [ $opts ... ] Dumb question. Does declaring `: dependency checks performed after depend-function declaration' and `: function' buy you anything other than readability via comments with syntax checking? > { > local fd=$1 > [ $# -gt 1 ] || return ${FAILURE-1} While working at IronPort, Doug (my tech lead) has convinced me that constructs like: if [ $# -le 1 ] then return ${FAILURE-1} fi Are a little more consistent and easier to follow than: [ $# -gt 1 ] || return ${FAILURE-1} Because some folks have a tendency to chain shell expressions, i.e. expr1 || expr2 && expr3 Instead of: if expr1 || expr2 then expr3 fi or... if ! expr1 then expr2 fi if [ $? -eq 0 ] then expr3 fi I've caught myself chaining 3 expressions together, and I broke that down into a simpler (but more longhand format), but I've caught people chaining 4+ expressions together, which just becomes unmanageable to follow (and sometimes bugs creep in because of operator ordering and expression evaluation and subshells, etc, but that's another topic for another time :)..). > shift 1 > printf "$@" >&$fd > } > > # eprintf $fmt [ $opts ... ] > # > # Print a message to stderr (fd=2). > # > : dependency checks performed after depend-function declaration > : function ; eprintf ( ) # $fmt [ $opts ... ] > { > fprintf 2 "$@" > } > > # show_deps > # > # Print the current list of dependencies. > # > : dependency checks performed after depend-function declaration > : function ; show_deps ( ) # > { > if [ "$SYSRC_SHOW_DEPS" = "1" ]; then > eprintf "Running internal dependency list:\n" > > local d > for d in $_depend; do > eprintf "\t%-15ss%s\n" "$d" "$( type "$d" )" The command(1) -v builtin is more portable than the type(1) builtin for command existence lookups (it just doesn't tell you what the particular item is that you're dealing with like type(1) does). I just learned that it also handles other builtin lexicon like if, for, while, then, do, done, etc on FreeBSD at least; POSIX also declares that it needs to support that though, so I think it's a safe assumption to state that command -v will provide you with what you need. > done > fi > } > > # die [ $err_msg ... ] > # > # Optionally print a message to stderr before exiting with failure status. > # > : dependency checks performed after depend-function declaration > : function ; die ( ) # [ $err_msg ... ] > { > local fmt="$1" > [ $# -gt 0 ] && shift 1 > [ "$fmt" ] && eprintf "$fmt\n" "$@" "x$fmt" != x ? It seems like it could be simplified to: if [ $# -gt 0 ] then local fmt=$1 shift 1 eprintf "$fmt\n" "$@" fi > show_deps > exit ${FAILURE-1} > } > > # have $anything > # > # Used for dependency calculations. Arguments are passed to the `type' > built-in > # to determine if a given command is available (either as a shell built-in or > # as an external binary). The return status is true if the given argument is > # for an existing built-in or executable, otherwise false. > # > # This is a convenient met
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Sat, Oct 9, 2010 at 10:36 AM, Devin Teske wrote: > > On Oct 9, 2010, at 10:03 AM, Garrett Cooper wrote: > >> On Thu, Oct 7, 2010 at 12:54 AM, Julian Elischer wrote: >>> On 10/7/10 12:23 AM, jhell wrote: Alright thank you for your explanation. I do not normally see this usage and this just sort of stood out at me and I did not want to assume what you were trying to accomplish, without asking. >>> >>> three useage cases come to mind immediately. >>> >>> 1/ use within other scripts.. >>> instead of the dozens of homegrown solutions people have written for puting >>> something >>> into /etc/rc.conf one can use this. >>> >>> 2/ what is the value of X on machines a,b,c >>> foreach machine in a b c >>> do >>> ssh $machine sysrc X >>> done >>> >>> you may well say "you could have used grep" bu tgrep doesn't give the >>> default value vie the >>> hierachy of .rc files. >>> 2A is of course to correc teh values found to be wrong with (2) >>> >>> 3/ on a really small system, without an editor this may do a cleaner job >>> than the usual >>> "grep -v X /etc/rc.conf >/tmp/x;echo X >> /tmp/x; mv /tmp/x /etc/rc.conf" >> >> I was going to say... >> >> 3A On a system where you're logged in via singleuser, sometimes >> terminal settings don't work correctly with editors (these days it's >> mostly because /usr isn't available so it can't load ncurses apps, >> some libs, termcap, etc). That would be a lifesaver in this case. > > I hadn't realized that. That's stupendous! > > Though I do believe that `/rescue/vi' exists these days as a > statically-linked binary (built using crunchgen(1) via > `rescue/rescue/Makefile' in the FreeBSD source tree). Yeah, but unfortunately if some filesystems aren't mounted [ /usr, /var, etc ] back in the 5.x days (that's when I got into FreeBSD) [until recently after ed@'s work on syscons and libteken?], most utilities like vi and ee are braindead when it comes to printing characters on the screen. I've screwed up and forgot to put down nfs shares as noauto a few times, and also tinkered around with ata <-> ahci within the past couple months, so until I learned enough sed to comment out lines in fstab, booting up my system didn't work out too well :/. >> But then I realized that this command probably would live in >> /usr/sbin and would probably need other apps in /usr/bin // /usr/sbin >> to run this command :). > > I envisioned it living in `/sbin' and it's actually free of dependencies to > external executables. If you execute it with the "-d" option ('d' for > 'dependencies'), you can see that it uses only shell internals. The only > thing this script truly depends on is `/bin/sh'. So it sounds like it would > fit the ability of working within single-user mode quite well (remember, I > developed it for embedded systems -- where things like grep/sed/awk may even > be missing). Guess it goes to show that I should review the code :). Thanks! -Garrett ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Oct 9, 2010, at 10:03 AM, Garrett Cooper wrote: > On Thu, Oct 7, 2010 at 12:54 AM, Julian Elischer wrote: >> On 10/7/10 12:23 AM, jhell wrote: >>> >>> Alright thank you for your explanation. I do not normally see this usage >>> and this just sort of stood out at me and I did not want to assume what >>> you were trying to accomplish, without asking. >> >> three useage cases come to mind immediately. >> >> 1/ use within other scripts.. >> instead of the dozens of homegrown solutions people have written for puting >> something >> into /etc/rc.conf one can use this. >> >> 2/ what is the value of X on machines a,b,c >> foreach machine in a b c >> do >> ssh $machine sysrc X >> done >> >>you may well say "you could have used grep" bu tgrep doesn't give the >> default value vie the >> hierachy of .rc files. >> 2A is of course to correc teh values found to be wrong with (2) >> >> 3/ on a really small system, without an editor this may do a cleaner job >> than the usual >> "grep -v X /etc/rc.conf >/tmp/x;echo X >> /tmp/x; mv /tmp/x /etc/rc.conf" > >I was going to say... > > 3A On a system where you're logged in via singleuser, sometimes > terminal settings don't work correctly with editors (these days it's > mostly because /usr isn't available so it can't load ncurses apps, > some libs, termcap, etc). That would be a lifesaver in this case. I hadn't realized that. That's stupendous! Though I do believe that `/rescue/vi' exists these days as a statically-linked binary (built using crunchgen(1) via `rescue/rescue/Makefile' in the FreeBSD source tree). >But then I realized that this command probably would live in > /usr/sbin and would probably need other apps in /usr/bin // /usr/sbin > to run this command :). I envisioned it living in `/sbin' and it's actually free of dependencies to external executables. If you execute it with the "-d" option ('d' for 'dependencies'), you can see that it uses only shell internals. The only thing this script truly depends on is `/bin/sh'. So it sounds like it would fit the ability of working within single-user mode quite well (remember, I developed it for embedded systems -- where things like grep/sed/awk may even be missing). > Thanks! > -Garrett > ___ > freebsd-hackers@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers > To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org" -- 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.te...@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 <- ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Thu, Oct 7, 2010 at 12:54 AM, Julian Elischer wrote: > On 10/7/10 12:23 AM, jhell wrote: >> >> Alright thank you for your explanation. I do not normally see this usage >> and this just sort of stood out at me and I did not want to assume what >> you were trying to accomplish, without asking. > > three useage cases come to mind immediately. > > 1/ use within other scripts.. > instead of the dozens of homegrown solutions people have written for puting > something > into /etc/rc.conf one can use this. > > 2/ what is the value of X on machines a,b,c > foreach machine in a b c > do > ssh $machine sysrc X > done > > you may well say "you could have used grep" bu tgrep doesn't give the > default value vie the > hierachy of .rc files. > 2A is of course to correc teh values found to be wrong with (2) > > 3/ on a really small system, without an editor this may do a cleaner job > than the usual > "grep -v X /etc/rc.conf >/tmp/x;echo X >> /tmp/x; mv /tmp/x /etc/rc.conf" I was going to say... 3A On a system where you're logged in via singleuser, sometimes terminal settings don't work correctly with editors (these days it's mostly because /usr isn't available so it can't load ncurses apps, some libs, termcap, etc). That would be a lifesaver in this case. But then I realized that this command probably would live in /usr/sbin and would probably need other apps in /usr/bin // /usr/sbin to run this command :). Thanks! -Garrett ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On 7.10.2010 15:42, Warren Block wrote: Consider also the docs that tell the user to echo 'something_enable="YES"' >> /etc/rc.conf which can produce duplicate and possibly differing entries. Or non-working entries if there was no ending \n present, or even a broken like forgetting to add two '>' and not having a backup :) rc.conf that breaks startup. -- S pozdravom / Best regards Daniel Gerzo ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Thu, 2010-10-07 at 17:36 +0200, Stefan Esser wrote: > Am 07.10.2010 05:29, schrieb Devin Teske: > > > > On Oct 6, 2010, at 4:09 PM, Brandon Gooch wrote: > > > >> On Wed, Oct 6, 2010 at 3:45 PM, Devin Teske wrote: > >>> Hello fellow freebsd-hackers, > >>> > >>> Long-time hacker, first-time poster. > >>> > >>> I'd like to share a shell script that I wrote for FreeBSD system > >>> administration. > >>> > >> > >> It seems the list ate the attachment :( > > > > > > Here she is ^_^ Comments welcome. > > Hi Devin, > > I think your script is quite useful in specific situations, but getting > it into FreeBSD may prove harder than you might have expected. > > But it should be easy to get it into the ports tree, if it proves > useful it may later make it into a new release (and be merged back) ... I'm willing to see that through to fruition. Should be fun. > Since I'm travelling with no access to my FreeBSD systems, I can not > verify all details in my reply, but I hope it is still useful for you. > > Let me start with a few remarks: > > Your script is really useful for querying of rc.conf (et al.) settings, > less so for modifications to the files (IMHO). The reasons are many: > > 1) Changes to rc.conf do not take effect, immediately (different from >sysctl(1) settings). Funny that you would mention that. How this script came-to-be is that I first developed the internal functions (sysrc() and sysrc_set()) for a larger script called "host- setup" which I'm programming for our company to allow field-engineers to setup their system using /usr/bin/dialog (dialog(1)). This larger script uses the internal sysrc() function to query values before presenting them to the user. Conversely, when the user invokes the editor to change the value, the script does the following -- say, for example, in changing the hostname: 1. It uses sysrc_set() to change the value in the rc.conf (or rc.conf.local -- or any other file mentioned in $rc_conf_files within /etc/defaults/rc.conf) 2. It then re-reads the value from the system configuration files. 3. Calls hostname(1) with the new value to make it effective without a reboot. So, in reality, this script (sysrc(8)) could be used by other scripts/programs in much the same way I use it -- as a way to munge the rc.conf(5) files *in addition to using standard utilities such as route (8), hostname(1), ifconfig(8) and many others. I agree that teaching this tool how to make changes effective without a reboot is neither warranted nor desired. Since each directive that can be munged by this utility indeed pertains to a different subsystem (some modify the behavior of /etc/rc, some modify the behavior or /etc/rc.sendmail, some /etc/rc.firewall, some /etc/rc. some modify the behaviour of /etc/rc.d/*), it's beyond the scope of this utility to know what to do with the given setting once changed to make it effective without a reboot. However, I will say that in a large-scale deployment, simply having an ability to do the following is still beneficial: for host in host1 host2 host3 host4 host5 ...; do ssh $host /bin/sh -c "'sysrc ntpdate_flags="..." && reboot'" done or, if you really know your shell-foo: for host in host1 host2 host3 host4 host5 ...; do ssh $host /bin/sh -c "'sysrc ntpdate_flags="..." && service ntpdate stop && service ntpdate start'" done > 2) Changes to rc.conf are persistent and need not be applied on each >reboot (similar to changes to sysctl.conf, but different from >sysctl(1)) I'm not sure what you mean by "changes ... are persistent", but yes, I do agree that the average lay person is convinced that a reboot is required to make any change to the rc.conf files effective (however, you and I perhaps know better). It should also be noted that sysctl.conf(5) does not require a reboot to re-apply the settings contained within. These days, one can run the following command to reload sysctl.conf(5): service sysctl reload Conversely, for a specific example of rc.conf(5) being read continuously after boot, we often have to restart apache, and we do-so like this: /usr/local/etc/rc.d/httpd restart The httpd script in /usr/local/etc/rc.d utilizes all the usual suspects in rc(8) rcorder(8) and `/etc/rc.subr'. In fact, just about every script in either /etc/rc.d or /usr/local/etc/rc.d will re-read /etc/rc.conf when run. No reboot required, just munge the file and run your rc(8) script either directly or via service(8). > 3) While there is a specified order of evaluation when reading from >rc.conf files, it is not obvious that writing to the last file in >$rc_conf_files that defined some parameter (or the first one, if >the parameter is not currently defined) is the right thing to do. >(E.g. if there is a rc.conf and rc.conf.local, it may well be the >latter that should receive new parameter definitions.) I've have previous incarnations of these utilities that DID go through each and every file listed in rc_c
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
Warren> Consider also the docs that tell the user to Warren>echo 'something_enable="YES"' >> /etc/rc.conf Warren> which can produce duplicate and possibly differing entries. Yup! Which is exactly why I like the idea of this tool. ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Thu, 7 Oct 2010, Douglas K. Rand wrote: I think that this script might also fill a void with using Puppet as a configuration tool. Currently Puppet, as its default behaviour, uses files in /etc/rc.conf.d to set variables. I've found this approach really lacking because you cannot do things like: nfs_server_enable="YES" via a /etc/rc.conf.d file because multiple things (like lockd, mountd, nfsd, nfsserver, and statd) all need nfs_server_enable set, as one example. This script would provide an easy method for puppet to "edit" lines in /etc/rc.conf. Consider also the docs that tell the user to echo 'something_enable="YES"' >> /etc/rc.conf which can produce duplicate and possibly differing entries. Or non-working entries if there was no ending \n present, or even a broken rc.conf that breaks startup. ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
I think that this script might also fill a void with using Puppet as a configuration tool. Currently Puppet, as its default behaviour, uses files in /etc/rc.conf.d to set variables. I've found this approach really lacking because you cannot do things like: nfs_server_enable="YES" via a /etc/rc.conf.d file because multiple things (like lockd, mountd, nfsd, nfsserver, and statd) all need nfs_server_enable set, as one example. This script would provide an easy method for puppet to "edit" lines in /etc/rc.conf. I have a feature request though: How about a switch like "-c config-file" to change which file sysrc_set adds the line to. We use both /etc/rc.conf and /etc/rc.conf.local on some systems, and it would be nice to be able to specify that this particular knob should be placed in /etc/rc.conf.local. I'm unsure what should happen if -c is specified and the knob you want to change already exists in another rc.conf file: Should it be moved to the new location, or changed where it is? (Maybe that'd be yet another option to sysrc.) ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On 10/7/10 12:23 AM, jhell wrote: Alright thank you for your explanation. I do not normally see this usage and this just sort of stood out at me and I did not want to assume what you were trying to accomplish, without asking. three useage cases come to mind immediately. 1/ use within other scripts.. instead of the dozens of homegrown solutions people have written for puting something into /etc/rc.conf one can use this. 2/ what is the value of X on machines a,b,c foreach machine in a b c do ssh $machine sysrc X done you may well say "you could have used grep" bu tgrep doesn't give the default value vie the hierachy of .rc files. 2A is of course to correc teh values found to be wrong with (2) 3/ on a really small system, without an editor this may do a cleaner job than the usual "grep -v X /etc/rc.conf >/tmp/x;echo X >> /tmp/x; mv /tmp/x /etc/rc.conf" ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On 10/07/2010 01:47, Devin Teske wrote: > > On Oct 6, 2010, at 9:49 PM, jhell wrote: > >> On 10/06/2010 23:29, Devin Teske wrote: >> >> I see no real advantage > > If you had to administer thousands of FreeBSD systems, you would. > Normally I have found large scale (1000's) of Unix like systems benefiting from the use of cfengine that is available via ports(7) and the use of other such software as Nagios, MUNIN for example that allow you to achieve quick deployment and monitoring of production systems. Not that this is a real comfortable solution to this either but the values contained throughout FreeBSD systems are also available via bsnmpd(1). > This script is obviously targeted to those for which are mentioned in > the header... "system administrators, power-users, and developers". > > > >> With that noted what advantage does this script bring compared to >> a script like service(8) that is already in the base system? > > service(8) clearly doesn't do what this script does. The values that > associate to an executable rc.d script are but only a fraction of > what rc.conf(5) is used for. See `/etc/defaults/rc.conf' for all > possible values. > I am well aware of its use and the values it contains for a majority of the FreeBSD releases, dating back to 4.2 ;) Before that time it was mostly Linux. > >> How much time does a end user spend enabling/disabling services for >> a system? > > In our environment? A script like this empowers support personnel and > engineers with the ability to perform a generalized query on > thousands of machines simultaneously and collate the results back > into a paging application (such as less(1) or more(1)), finding > possible misconfigurations, problems, or other issues that arise by > human error, script error, or legacy options languishing from an > upgrade process. Further, with the ability to set options, it makes > remediating problems quite easy. > Alright, understandable. Large scale environments don't really fit into the PAGER area but I am following you. > >> How much of a difference in time would this make to the end user as >> per say just having to echo a variable into an rc.conf? > > That's a sloppy way to manage production equipment/environments. > Remember, there is a very few examples of your script to go on for usage and really not much real example usage scenarios that at least I can relate to by giving the script a quick look-over without getting really deep into it (yet). This is why the probing questions are coming up and that will at least help me if not others build a scenario at which your script can be looked at in possibly a more correct manner rather than passing judgment. > >> If this would be put in place into the base system where would it >> be and who would maintain it ? > > It would likely be placed in the same directory as sysctl(8) > (/sbin/sysrc). > > I would maintain it. > > >> Is it feasible to expect an end user to read rc.conf(5) >> services(8) while also consuming knowledge of etc/defaults/rc.conf >> & boot(8) as well sysctl.conf(5) and loader.conf(5). > > A friend of mine and I just installed 8.1-RELEASE-p1 onto his laptop. > We had to go through all those man-pages and more to get everything > good with the wpa_supplicant_* options. We didn't have to go to > google, bing, wolfram alpha, barnes & noble, or any place... all the > answers for setting up his laptop using 802.11g tied to a WAP w/ > WPA2. > > But what does that have to do with the price of bread in China? > Well unless those bread factories machines are powered by FreeBSD, I hope not much. ;) > This script helps system administrators, power-users, and developers. > It's designed to make the task of performing non-interactive edits to > rc.conf(5) not only easier, but cleaner. The files are left fully > in-tact by the script, which is the important part to note. It's not > going to sloppily keep tacking on new values for the same directive > if the script is called 1,000 times over. This enables such things as > being called from cron on a regular basis even. > > >> Also you search for grep and awk in your script. > > No. I check for the presence of them with $PATH expansion. > > The have() function is a one-line function that remaps the `type' > shell built-in to have no output, yet still return the error status > (or lack thereof). If you read the sh(1) manual, you'll see that the > `type' built-in can be passed a shell keyword, a shell function, or > failing that, it will find the executable via $PATH expansion, and > failing that will return error status. The have() function that I > have defined in my script allows me to do this: > > if have grep; then # use grep else # use case with glob(7) pattern > matching fi > > >> If this were to be in base, then utilities like this would not need >> to be searched for as base utilities are generally static to where >> they live in the file-system already... /usr/bin/gr
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Oct 6, 2010, at 9:49 PM, jhell wrote: > On 10/06/2010 23:29, Devin Teske wrote: > > I see no real advantage If you had to administer thousands of FreeBSD systems, you would. This script is obviously targeted to those for which are mentioned in the header... "system administrators, power-users, and developers". > With that noted what advantage does this script bring compared to a > script like service(8) that is already in the base system? service(8) clearly doesn't do what this script does. The values that associate to an executable rc.d script are but only a fraction of what rc.conf(5) is used for. See `/etc/defaults/rc.conf' for all possible values. > How much time does a end user spend enabling/disabling services for a > system? In our environment? A script like this empowers support personnel and engineers with the ability to perform a generalized query on thousands of machines simultaneously and collate the results back into a paging application (such as less(1) or more(1)), finding possible misconfigurations, problems, or other issues that arise by human error, script error, or legacy options languishing from an upgrade process. Further, with the ability to set options, it makes remediating problems quite easy. > How much of a difference in time would this make to the end user as per > say just having to echo a variable into an rc.conf? That's a sloppy way to manage production equipment/environments. > If this would be put in place into the base system where would it be and > who would maintain it ? It would likely be placed in the same directory as sysctl(8) (/sbin/sysrc). I would maintain it. > Is it feasible to expect an end user to read rc.conf(5) services(8) > while also consuming knowledge of etc/defaults/rc.conf & boot(8) as well > sysctl.conf(5) and loader.conf(5). A friend of mine and I just installed 8.1-RELEASE-p1 onto his laptop. We had to go through all those man-pages and more to get everything good with the wpa_supplicant_* options. We didn't have to go to google, bing, wolfram alpha, barnes & noble, or any place... all the answers for setting up his laptop using 802.11g tied to a WAP w/ WPA2. But what does that have to do with the price of bread in China? This script helps system administrators, power-users, and developers. It's designed to make the task of performing non-interactive edits to rc.conf(5) not only easier, but cleaner. The files are left fully in-tact by the script, which is the important part to note. It's not going to sloppily keep tacking on new values for the same directive if the script is called 1,000 times over. This enables such things as being called from cron on a regular basis even. > Also you search for grep and awk in your script. No. I check for the presence of them with $PATH expansion. The have() function is a one-line function that remaps the `type' shell built-in to have no output, yet still return the error status (or lack thereof). If you read the sh(1) manual, you'll see that the `type' built-in can be passed a shell keyword, a shell function, or failing that, it will find the executable via $PATH expansion, and failing that will return error status. The have() function that I have defined in my script allows me to do this: if have grep; then # use grep else # use case with glob(7) pattern matching fi > If this were to be in > base, then utilities like this would not need to be searched for as base > utilities are generally static to where they live in the file-system > already... /usr/bin/grep /usr/bin/awk for example. I do not think it > makes much sense for a base utility to search outside of its world for a > executable especially for grep(1) and awk(1). Call these directly and > let the end user modify their PATH as to where the location of these > would actually be called from rather than adding extra complicity. The integral point of confusion is lack of knowledge that have() is `type' which already performs $PATH expansion. I'm not probing for their location, I'm testing for their existence so that I can use the name. Think of it like a `try' statement. >> -> 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. > Due to this disclaimer I am not sure that even the implicit BSD license > can override this. Though there is a thin gray line here, it might be > suitable to remove this from future email unless you are specifically > addressing something to a specific person. Please. If you read it (as have I many times) it means nothing more than that I own the IP rights to what I wrote and that if you ar
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On 10/06/2010 23:29, Devin Teske wrote: I am not saying this to sound like I am shooting down this script but from the looks of it, I see no real advantage over the way a FreeBSD system is configured already. You could probably point these out though. With that noted what advantage does this script bring compared to a script like service(8) that is already in the base system? How much time does a end user spend enabling/disabling services for a system? How much of a difference in time would this make to the end user as per say just having to echo a variable into an rc.conf? If this would be put in place into the base system where would it be and who would maintain it ? Is it feasible to expect an end user to read rc.conf(5) services(8) while also consuming knowledge of etc/defaults/rc.conf & boot(8) as well sysctl.conf(5) and loader.conf(5). Also you search for grep and awk in your script. If this were to be in base, then utilities like this would not need to be searched for as base utilities are generally static to where they live in the file-system already... /usr/bin/grep /usr/bin/awk for example. I do not think it makes much sense for a base utility to search outside of its world for a executable especially for grep(1) and awk(1). Call these directly and let the end user modify their PATH as to where the location of these would actually be called from rather than adding extra complicity. > -> 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. Due to this disclaimer I am not sure that even the implicit BSD license can override this. Though there is a thin gray line here, it might be suitable to remove this from future email unless you are specifically addressing something to a specific person. Regards, -- jhell,v ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Oct 6, 2010, at 8:29 PM, Devin Teske wrote: > > On Oct 6, 2010, at 4:09 PM, Brandon Gooch wrote: > >> On Wed, Oct 6, 2010 at 3:45 PM, Devin Teske wrote: >>> Hello fellow freebsd-hackers, >>> >>> Long-time hacker, first-time poster. >>> >>> I'd like to share a shell script that I wrote for FreeBSD system >>> administration. >>> >> >> It seems the list ate the attachment :( > > > Here she is ^_^ Comments welcome. > Again with the patch needed... :( Was testing embedded environment sans-grep(1). dte...@dt.vicor.com bin $ diff -pu sysrc{.orig,} --- sysrc.orig 2010-10-06 20:47:55.0 -0700 +++ sysrc 2010-10-06 20:48:06.0 -0700 @@ -492,8 +492,7 @@ depend sysrc_set 'local' 'sysrc' '[' 're local found= local regex="^[[:space:]]*$varname=" for file in $conf_files; do - #if have grep; then - if false; then + if have grep; then grep -q "$regex" $file && found=1 else while read LINE; do \ @@ -529,8 +528,7 @@ depend sysrc_set 'local' 'sysrc' '[' 're ( found= while read -r LINE; do if [ ! "$found" ]; then - #if have grep; then - if false; then + if have grep; then match="$( echo "$LINE" | grep "$regex" )" else case "$LINE" in > #!/bin/sh > # -*- tab-width: 4 -*- ;; Emacs > # vi: set tabstop=4 :: Vi/ViM > # > # Revision: 1.0 > # Last Modified: October 6th, 2010 > COPYRIGHT > # > # (c)2010. Devin Teske. All Rights Reserved. > # > # Redistribution and use in source and binary forms, with or without > # modification, are permitted provided that the following conditions > # are met: > # 1. Redistributions of source code must retain the above copyright > #notice, this list of conditions and the following disclaimer. > # 2. Redistributions in binary form must reproduce the above copyright > #notice, this list of conditions and the following disclaimer in the > #documentation and/or other materials provided with the distribution. > # > # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE > # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > # SUCH DAMAGE. > # > # AUTHOR DATE DESCRIPTION > # dteske 2010.09.29 Initial version. > # > INFORMATION > # > # Command Usage: > # > # sysrc [OPTIONS] name[=value] ... > # > # OPTIONS: > # -h --help Print this message to stderr and exit. > # -d Print list of internal dependencies before exit. > # -e Print query results as `var=value' (useful for producing > # output to be fed back in). Ignored if -n is specified. > # -n Show only variable values, not their names. > # > # ENVIRONMENT: > # SYSRC_SHOW_DEPS Dump list of dependencies. Must be zero or one > # (default: `0') > # RC_DEFAULTS Location of `/etc/defaults/rc.conf' file. > # > # About the Utility: > # > # This utility works similar to sysctl(8). It shares the `-e' and `-n' > # options (detailed above and in sysctl(8)) and also has the same > # `name[=value]' syntax for querying/setting configuration options. > # > # Fundamentally it could be said that sysctl(8) munges sysctl MIBs in the > # entrant kernel, while sysrc(8) -- this utility -- munges values in the > # system rc.conf(5) configuration files. > # > # NOTE: System configuration files are by-default configured in the file > # `/etc/defaults/rc.conf' in the variable `rc_conf_files', which by-default > # contains a space-separated list of pathnames. On all FreeBSD systems, this > # defaults to the value "/etc/rc.conf /etc/rc.conf.local". Each pathname is > # sourced in-order upon startup. It is in the same fashion that this script > # sources the configuration files before returning the value of the given > # variable by-name. > # > # When you supply this utility with a variable name, it will return the > value > # of the variable. If the variable does not appear in any of the configured
Re: sysrc -- a sysctl(8)-like utility for managing /etc/rc.conf et. al.
On Oct 6, 2010, at 4:09 PM, Brandon Gooch wrote: > On Wed, Oct 6, 2010 at 3:45 PM, Devin Teske wrote: >> Hello fellow freebsd-hackers, >> >> Long-time hacker, first-time poster. >> >> I'd like to share a shell script that I wrote for FreeBSD system >> administration. >> > > It seems the list ate the attachment :( Here she is ^_^ Comments welcome. #!/bin/sh # -*- tab-width: 4 -*- ;; Emacs # vi: set tabstop=4 :: Vi/ViM # # Revision: 1.0 # Last Modified: October 6th, 2010 COPYRIGHT # # (c)2010. Devin Teske. All Rights Reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright #notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright #notice, this list of conditions and the following disclaimer in the #documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # AUTHOR DATE DESCRIPTION # dteske 2010.09.29 Initial version. # INFORMATION # # Command Usage: # # sysrc [OPTIONS] name[=value] ... # # OPTIONS: # -h --help Print this message to stderr and exit. # -d Print list of internal dependencies before exit. # -e Print query results as `var=value' (useful for producing # output to be fed back in). Ignored if -n is specified. # -n Show only variable values, not their names. # # ENVIRONMENT: # SYSRC_SHOW_DEPS Dump list of dependencies. Must be zero or one # (default: `0') # RC_DEFAULTS Location of `/etc/defaults/rc.conf' file. # # About the Utility: # # This utility works similar to sysctl(8). It shares the `-e' and `-n' # options (detailed above and in sysctl(8)) and also has the same # `name[=value]' syntax for querying/setting configuration options. # # Fundamentally it could be said that sysctl(8) munges sysctl MIBs in the # entrant kernel, while sysrc(8) -- this utility -- munges values in the # system rc.conf(5) configuration files. # # NOTE: System configuration files are by-default configured in the file # `/etc/defaults/rc.conf' in the variable `rc_conf_files', which by-default # contains a space-separated list of pathnames. On all FreeBSD systems, this # defaults to the value "/etc/rc.conf /etc/rc.conf.local". Each pathname is # sourced in-order upon startup. It is in the same fashion that this script # sources the configuration files before returning the value of the given # variable by-name. # # When you supply this utility with a variable name, it will return the value # of the variable. If the variable does not appear in any of the configured # rc_conf_files, an error is printed and we return with error status. # # When changing values of a given variable it does not matter if the variable # appears in any of the rc_conf_files or not. If the variable does not appear # in any of the files, it is appended to the end of the first pathname in the # rc_conf_files variable. Otherwise, the sysrc_set() function will replace # only the last-occurrence in the last-file found to contain the variable. # This effectively gets the value to take effect next reboot without heavily # modifying these integral files (yet taking care not to allow the file to # grow unweildy should the script be called repeatedly infinitum). # # About the Code: # # I hope that you enjoy the cleanliness, verbosity (but at the same time, # utilitarian brevity) and -- dare I say -- beauty of the code of this # utility. I have been refining my cross-platform/POSIX-compliant/baseline- # compatible method of pure-bourne shell scripting for 10 years now. Shell is # not the only language that I could have chosen to written this utility in, # but it assuredly was the most satisfying. Satisfying in the sense that such # a utility is infinitely more useful to the masses if programmed in the # ba