From: Eric on
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
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
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
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
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]