From: Eric on 13 Dec 2009 12:13 On 2009-12-13, Sven Mascheck <mascheck(a)email.invalid> wrote: > Eric wrote: >> On 2009-12-13, Dave <foo(a)coo.com> wrote: > >>> set -- `env LC_ALL=C LC_TIME=C LANG=C date -u '+%Y %j %H %M %S'` > >>> [...] to save messing up someone's environment? > >> This is what env is for - it sets the environment variables it is given >> and then runs the specified command. It does this in its own process, >> so the environment it creates applies _only_ to the command it runs. > > Pedantic footnote: in the above, there's no need to use > "env var=value command", because "var=value command" behaves the same > (ignoring other features of env for now). And that's what I would have done myself (though I'm often amazed how few people seem to be aware of it). But I didn't mention it because I just answered the questions, and I thought it might come up in a followup posting :) . Eric
From: Stephane CHAZELAS on 14 Dec 2009 02:19 2009-12-13, 10:02(+00), Dave: > I was looking back at the thread: > "getting time since epoch using shell commands? (Bourne Shell)" > > http://groups.google.com/group/comp.unix.shell/browse_thread/thread/121344445ef2c75a/e4903a12920f4c?hl=en&ie=UTF-8&q=seconds+since+epoch+comp.unix.shell > > and in particular this post > > http://groups.google.com/group/comp.unix.shell/msg/fe44b83b56478e36?hl=en > > where this snippet of code was posted. > > if type env >/dev/null 2>&1 ; then > set -- `env LC_ALL=C LC_TIME=C LANG=C date -u '+%Y %j %H %M %S'` > else > set -- `date -u '+%Y %j %H %M %S'` > fi > > > I'm trying to understand Strange indeed. First env is a mandatory POSIX command, it's as unlikely to find a system without env as one without date, and those wouldn't be Unix nor POSIX systems. On the other hand, "type" is optional in POSIX (but required for a Unix system). So that first line is more likely to test for the existence of the type command than the env one. I also beleive that some old versions of type failed to set the exit status correctly upon not-found commands. Then, as already pointed out, env is unnecessary as every Bourne like shell supports LC_ALL=C date ... To pass that LC_ALL variable in the environment to the date command. Then, LC_ALL overrides all the LC_* and LANG_ variables, so the above is equivalent of set -- `LC_ALL=C date -u '+%Y %h %H %M %S'` and as you pointed out, localisation is unlikely to have any influence on those numeric date components. > 3) If they are set in a script, with > set -- `env LC_ALL=C LC_TIME=C LANG=C date -u '+%Y %j %H %M %S'` > > would one need to save their old values first, then restore them, to save > messing up someone's environment? Since the script I want will only get print > the seconds since the epoch, then exit, I doubt this is necessary, as the > settings of the 3 variables will not be needed in that script. But I do not wish > to mess up someone's environment variables. Note that environment is something passed accross execution of a command (in the exact same way as the list of arguments). Command substitution (`...` or $(...)) creates a separate shell environment (in most shells implemented by forking a subshell), so any modification to the environment made in there will only apply in there, so you could have written: set -- ` LC_ALL=C export LC_ALL date -u ... ` env LC_ALL=C date and LC_ALL=C date, only pass that variable to the date command. > > 4) What does 'set --' do? The man page says > > " -- Does not change any of the flags. This option is > use- ful in setting $1 to -." > > > but I just do not understand this. Can someone explain it in a > bit more detail. [...] "set" has three functions: 1- without argument, it prints the shell variables along with their values 2- with arguments starting with "-", it toggles some behaviors of the shell (generally equivalent to start the shell with those options). 3- other arguments are used to set the positional parameters ($1, $2...). "set a b" sets $1=a and $2=b so does set -- a b You use -- to make sure you always use that 3rd usage of set, even when the list of arguments may be empty (as in when the date command fails above) or may start with a "-" (for negative years above for instance). It's a good habit to always use -- above. -- St�phane
From: Stephane CHAZELAS on 14 Dec 2009 02:50 2009-12-13, 12:20(+00), Eric: [...] >> 4) What does 'set --' do? The man page says >> >> " -- Does not change any of the flags. This option is use- >> ful in setting $1 to -." >> >> >> but I just do not understand this. Can someone explain it in a bit more detail. >> > > The -- means "ignore me, but nothing from here on is an option even if > it starts with a -". [...] It also prevents the behavior whereby set outputs the list of shell variables when not passed any argument. -- St�phane
From: Sven Mascheck on 14 Dec 2009 19:38 Stephane CHAZELAS wrote: > I also beleive that some old versions of type failed to > set the exit status correctly upon not-found commands. Several Bourne shell variants show this, because for some reason it was not implemented in the main line until SVR4.2. So some vendors added it themselves; I know the OSF1 SVR2 sh, AIX SVR3 sh, SunOS5 and IRIX5 SVR4 sh. It seems "type" was neglected from time to time. Perhaps it was considered an interactive debugging command only? The descriptive output backs this suspicion. Almquist even forgot to implement it in his SVR4 sh reimplementation. And it might not have been missed badly on the traditional BSDs, because it was not before the free BSDs, that type was "re-added". By the way: in the 8th ed unix, Dennis Ritchie improved the design a bit and replaced "type" with "whatis" which produces output which can be re-evaluated by the shell: "[...] parameters are printed as assign- ments, functions as their definitions, builtins as calls to builtin, and binaries as their full pathnames."
From: Sven Mascheck on 14 Dec 2009 20:20
Stephane CHAZELAS wrote: > I also beleive that some old versions of type failed to > set the exit status correctly upon not-found commands. Several Bourne shell variants show this, because for some reason an appropriate exit status was not implemented in the main line until SVR4.2. So some vendors added that themselves; I know the OSF1 SVR2 sh, AIX SVR3 sh, SunOS5 and IRIX5 SVR4 sh. It seems "type" was neglected from time to time. Perhaps it was considered an interactive debugging command only? The descriptive output backs this suspicion. Almquist even forgot to implement type at all in his ash, a SVR4 sh reimplementation. And it might not have been missed badly on the traditional BSDs, because it was not before the free BSDs, that "type" was added again. By the way: in the 8th ed unix (with a SVR2 derived shell), Dennis Ritchie improved the design a bit and replaced "type" with "whatis", which produces output which can be re-evaluated by the shell: "[...] parameters are printed as assignments, functions as their definitions, builtins as calls to builtin, and binaries as their full pathnames." [superseding ambiguities in my 1st post] |