Hey.

Georgios, your suggestion has some problems:
- it doesn't take care of (accidental) multiple definitions of these
  settings (in which case obviously the last one wins).
- apparently variables set in login.defs may start with whitespace.
- according to login.defs(5), PATH= may be omitted, in which case your
  patch breaks.
- it overwrites the PATH when already set, which IMHO it shouldn't



Michael,
- your 2nd version uses /proc, thus it wouldn't work on non-Linuxes and
  therefore I don't even comment to it further.
- I'm afraid I don't understand what you do with the IFS and it seems
  overly complex:
  - What's "ifs=${IFS+_$IFS}" some bashism? And what if the user's
    calling environment would have "ifs" and/or _$IFS already used
    somehow?
    Same for pathkey key val ... these don't seem like names that noone
    would ever use.
  - since you probably just set it for the read, why not:
    IFS="" read -r ...
    ?
  - you have the same problems as Georgios above, at least the thing
    with the whitespace 



I'd propose the following solution, which addresses the above problem
with only one "disadvantage":
- I call out 4 processes, but only in the case that PATH isn't already
  set, which should basically never happen, as login (or maybe even PAM
  on some systems) already does that for us.



PATH="${PATH:-"$( { /bin/sed -n "s/^[[:space:]]*ENV_$(if [ "$(/usr/bin/id -u)" 
= 0 ]; then /usr/bin/printf SU; 
fi)PATH[[:space:]][[:space:]]*\(\|PATH=\)\(.*\)$/\2/p" /etc/login.defs | 
/usr/bin/tail -n 1; } 2> /dev/null )"}"



- POSIX sh compatible
  AFAICS, I also don't use any non POSIX options to the POSIX tools.
- The tools I call: sed, id, printf, tail
  are all from essential+required packages, and even busybox contains
  them.
- PATH isn't overwritten if already set (but it is if unset or "")
- leading whitespace accepted
- with the tail I use the last definition of the setting
- full paths to the tools are required, since the current PATH may be
  bogus, unset or ""
- any errors are sent to /dev/null (but it's unlikely that this would
  ever fail, probably only when the tools are not found or no memory is
  left.
  And even then, the worst likely thing is that an unset/"" PATH is
  overwritten with a "" PATH

If Santiago likes one could even add another layer of ${:-foo} around,
which kicks in if no PATH info is found from login.defs, and then again
sets the hardcoded PATH as now... or even look at other sources first
(are there any?)

The only problem then is that one likely needs to invoke id more often.
Using a local e.g. in a function
determine_path()
{
   local UID="$(/usr/bin/id -u)"
   #plus more voodoo
}
wouldn't solve the problem, a) "local" is strictly speaking not POSIX,
IIRC, b) one would overwrite a function the user might have possible set
outside.
A real solution would be to don't set it, but do everything from within
a (); subshell, e.g.
PATH="$( ( \
       UID="$(/usr/bin/id -u)"
       #plus more voodoo
       prtinf "some path in the end"
     ) )"
Don't forget the spaces between the braces,... otherwise it would try
arithmetic expansion.


Cheers,
Chris.

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to