Hi Laurent, Answers embedded
On 26/10/2019 4:27 pm, Laurent Bercot wrote:
>> I'd mistakenly assumed execlineb knew where its friends were; though in
>> hindsight its a bit much to assume that execlineb internally changes the
>> PATH.
>
> The real question is, why is there a "umask" binary that's not the one
> from execline? Non-chainloading non-builtin umask is nonsense, just
> like non-chainloading non-builtin cd.
>
I can only shed a ray of light, though this /usr/bin/umask has been
around for some time. I fired up an old FreeBSD 9.2 system that has it.
Content being:
#!/bin/sh
# $FreeBSD: stable/9/usr.bin/alias/generic.sh 151635 2005-10-24
22:32:19Z cperciva $
# This file is in the public domain.
builtin ${0##*/} ${1+"$@"}
which is the same as 12.1. Why? I can only refer to src logs:
...
r151635 | cperciva | 2005-10-25 08:32:19 +1000 (Tue, 25 Oct 2005) | 10 lines
Use the "builtin" shell function to make sure that the requested
command is handled as a shell function. This avoids the following
peculiar behaviour when /usr/bin is on a case-insensitive filesystem:
# READ foo
(... long pause, depending upon the amount of swap space available ...)
sh: Resource temporarily unavailable.
...
r100200 | wollman | 2002-07-17 08:16:05 +1000 (Wed, 17 Jul 2002) | 5 lines
A little bit more thought has resulted in a generic script which can
implement any of the useless POSIX-required ``regular shell builtin''
utilities, saving one frag and one inode each. The script moves to
usr.bin/alias which is alphabetically the first of these commands.
the last entry before the cvs logs were transferred to svn.
Examining the Makefile/usr/src/usr.bin/alias/Makefile
# $FreeBSD: stable/12/usr.bin/alias/Makefile 284255 2015-06-11 04:22:17Z
sjg $
SCRIPTS=generic.sh
SCRIPTSNAME=alias
LINKS= ${BINDIR}/alias ${BINDIR}/bg \
${BINDIR}/alias ${BINDIR}/cd \
${BINDIR}/alias ${BINDIR}/command \
${BINDIR}/alias ${BINDIR}/fc \
${BINDIR}/alias ${BINDIR}/fg \
${BINDIR}/alias ${BINDIR}/getopts \
${BINDIR}/alias ${BINDIR}/hash \
${BINDIR}/alias ${BINDIR}/jobs \
${BINDIR}/alias ${BINDIR}/read \
${BINDIR}/alias ${BINDIR}/type \
${BINDIR}/alias ${BINDIR}/ulimit \
${BINDIR}/alias ${BINDIR}/umask \
${BINDIR}/alias ${BINDIR}/unalias \
${BINDIR}/alias ${BINDIR}/wait
and yes they exist in /usr/bin/
>From tcsh
# which cd
cd: shell built-in command.
>From sh
# which echo
/bin/echo
Ok - that's done my head in.
>
>> Unfortunately it seems that the path can't be set within execlineb
>> context.
>
> Of course it can. What's happening is that both export and envfile
> set the PATH *on execution of the next command*, so the command that's
> right after them will still be searched with the old PATH. In other words:
>
> "export PATH /usr/local/bin umask 033 echo blah" will not work, because
> umask will still be searched for in the old PATH (but echo would be
> searched in the new PATH), but
> "export PATH /usr/local/bin exec umask 033 echo blah" will work, because
> exec is searched in the old PATH and umask is searched in the new PATH.
>
> (exec is an execline nop that can be useful in those cases, if you
> don't have another command to put between the export PATH and the
> command you need to search in the new PATH.)
>
Thank-you, the explanation helps. I guess through bad experiences with
(non-execline) exec, I avoid it unless I really do want to transfer
control to it.
I think with this example
# rm -v /tmp/t1 ; setenv PATH
/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin ; execlineb -Pc 'importas
op PATH emptyenv export PATH /usr/local/bin:$op exec umask 002 redirfd
-w 1 /tmp/t1 echo blah4' ; /bin/ls -l t1 ; cat /tmp/t1
/tmp/t1
-rw-rw-r-- 1 root wheel 6 26 Oct 18:02 t1
blah4
Due to the above discussion around umask, I will have to consider either
adding to my execline scripts :(
importas op PATH
emptyenv
export PATH /usr/local/bin:$op
or explicit paths as needed.
Thank-you to the contributors for your patience.