Discussion:
[PATCH] ash: make bash_source command search current directory after PATH
Paul Otto
2018-01-26 08:34:52 UTC
Permalink
This patch restores, and improves upon, expected behavior to BASH
compatibility which was lost beginning with 1.27.0. This was pulled into
Alpine 3.7 which, in turn was pulled into official Docker images beginning
with docker:17.12. As a result, a large number of CICD builds that use
"source filename" have broken everywhere.

According to the BASH documentation, the source command should:
Read and execute commands from filename in the current shell
environment and return the exit status of the last command executed from
filename. If filename does not contain a slash, filenames in PATH are
used to find the directory containing filename. The file searched for in
PATH need not be executable. When bash is not in posix mode,
the current directory is searched if no file is found in PATH.

This patch specifically checks for when commandname is "source", and only
performs the additional PWD search in that case, and only after it has
neither 1) short-circuited from a /; and 2) not been found somewhere within
the PATH.

shell/ash.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git i/shell/ash.c w/shell/ash.c
index 865159d20..6de68bc4d 100644
--- i/shell/ash.c
+++ w/shell/ash.c
@@ -12967,7 +12967,10 @@ find_dot_file(char *name)
if (strchr(name, '/'))
return name;

- while ((fullname = path_advance(&path, name)) != NULL) {
+ while ((fullname = path_advance(&path, name)) != NULL) {
+#if BASH_SOURCE
+ try_cur_dir:
+#endif
if ((stat(fullname, &statb) == 0) &&
S_ISREG(statb.st_mode)) {
/*
* Don't bother freeing here, since it will
@@ -12980,7 +12983,14 @@ find_dot_file(char *name)
}

/* not found in the PATH */
- ash_msg_and_raise_error("%s: not found", name);
+#if BASH_SOURCE
+ if (strcmp(commandname, "source") == 0) {
+ fullname = name;
+ goto try_cur_dir;
+ }
+#endif
+ /* not found at all */
+ ash_msg_and_raise_error("%s: not found", name);
/* NOTREACHED */
}
Denys Vlasenko
2018-01-26 14:15:35 UTC
Permalink
Post by Paul Otto
This patch restores, and improves upon, expected behavior to BASH
compatibility which was lost beginning with 1.27.0. This was pulled into
Alpine 3.7 which, in turn was pulled into official Docker images beginning
with docker:17.12. As a result, a large number of CICD builds that use
"source filename" have broken everywhere.
Read and execute commands from filename in the current shell environment
and return the exit status of the last command executed from filename. If
filename does not contain a slash, filenames in PATH are used to find the
directory containing filename. The file searched for in PATH need not be
executable. When bash is not in posix mode, the current directory is
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
Post by Paul Otto
This patch specifically checks for when commandname is "source"
This is not how bash behaves. It treats "." and "source" the same.
Post by Paul Otto
and only
performs the additional PWD search in that case, and only after it has
neither 1) short-circuited from a /; and 2) not been found somewhere within
the PATH.
I think this should be made a config option, off by default.
Paul Otto
2018-01-26 16:46:31 UTC
Permalink
This post might be inappropriate. Click to display it.
Denys Vlasenko
2018-01-27 17:15:23 UTC
Permalink
I already committed a similar patch to git.
Post by Paul Otto
I have modified this patch per your review comments. For what it's worth, I
went through hush, and found that it still exhibits the BASH non-POSIXy
static char *find_in_path(const char *arg)
{
...
if (sz != 0) {
ret = xasprintf("%.*s/%s", sz, PATH, arg);
} else {
/* We have xxx::yyyy in $PATH,
* it means "use current dir" */
ret = xstrdup(arg);
}
if (access(ret, F_OK) == 0)
break;
...
----
static int FAST_FUNC builtin_source(char **argv)
{
...
if (!strchr(filename, '/')) {
arg_path = find_in_path(filename);
if (arg_path)
filename = arg_path;
}
...
----
shell/ash.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git i/shell/ash.c w/shell/ash.c
index 865159d20..c9edce16c 100644
--- i/shell/ash.c
+++ w/shell/ash.c
@@ -60,6 +60,20 @@
//config: from GNU bash, which allows for alternative command not
found
//config: handling.
+//config:config ASH_BASH_NON_POSIX_DOTCMD
+//config: bool "non-POSIXy dotcmd behavior (ie: . <file> or source
<file>)"
+//config: default n
+//config: depends ASH_BASH_COMPAT
+//config: help
+//config: Activates the expected, non-POSIXy behavior BASH follows
when
+//config: dotcmd is invoked with either ". <file>" or "source <file>".
In
+//config: BASH, when the dotcmd is combined with a filename without an
+//config: absolute or relative path specified, the shell first scans
the
+//config: environment's PATH, followed by the present working
directory
+//config: (PWD). The POSIX-compliant command does NOT scan the present
+//config: working directory. This option is disabled by default for
improved
+//config: speed and security.
//config:config ASH_JOB_CONTROL
//config: bool "Job control"
//config: default y
@@ -12967,7 +12981,10 @@ find_dot_file(char *name)
if (strchr(name, '/'))
return name;
- while ((fullname = path_advance(&path, name)) != NULL) {
+ while ((fullname = path_advance(&path, name)) != NULL) {
+#if ASH_BASH_NON_POSIX_DOTCMD
+#endif
if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode))
{
/*
* Don't bother freeing here, since it will
@@ -12980,7 +12997,12 @@ find_dot_file(char *name)
}
/* not found in the PATH */
- ash_msg_and_raise_error("%s: not found", name);
+#if ASH_BASH_NON_POSIX_DOTCMD
+ fullname = name;
+ goto try_cur_dir;
you can simply "return name" here.
Post by Paul Otto
+#endif
+ /* not found at all */
+ ash_msg_and_raise_error("%s: not found", name);
/* NOTREACHED */
}
Paul Otto
2018-01-27 21:05:46 UTC
Permalink
Thanks for taking care of this, Denys. It didn't wind up the way I'd hoped,
but at least it is predictable both ways now. I will see if there is a way
to get Alpine Linux to build with that config option set, to resolve the
regression introduced by busybox 1.27.

- Paul
Kang-Che Sung
2018-01-28 03:16:19 UTC
Permalink
2018幎1月28日 䞊午5:05"Paul Otto" <***@ottoops.com>寫道

Thanks for taking care of this, Denys. It didn't wind up the way I'd hoped,
but at least it is predictable both ways now. I will see if there is a way
to get Alpine Linux to build with that config option set, to resolve the
regression introduced by busybox 1.27.


I wonder when people suggest adding a config option to make "source"/"."
command bash-compatible, why aren't they bothered to append the "."
directory at the end of $PATH and save the bloat on the shell code.

Also, I suggest the new BASH_SOURCE_CURDIR be _one_ config option across
both shells, instead of allowing different behaviors of two shells in one
binary. And since this is about behavior change and not a feature
"extension", I think we have no need for this config option to depend on
*_BASH_COMPAT.
William Pitcock
2018-01-29 15:48:59 UTC
Permalink
Hello,
Post by Paul Otto
Thanks for taking care of this, Denys. It didn't wind up the way I'd hoped,
but at least it is predictable both ways now. I will see if there is a way
to get Alpine Linux to build with that config option set, to resolve the
regression introduced by busybox 1.27.
This is done in 3.7 and edge as busybox-1.27.2-r8. Relevant commit:
https://git.alpinelinux.org/cgit/aports/commit/?id=fae8e63b4df5c1052fc79ed551d442263ddcb523

William
Paul Otto
2018-01-29 16:43:25 UTC
Permalink
Thanks for the heads up, William! Great to hear!

Thanks,
Paul
Post by William Pitcock
Hello,
Post by Paul Otto
Thanks for taking care of this, Denys. It didn't wind up the way I'd
hoped,
Post by Paul Otto
but at least it is predictable both ways now. I will see if there is a
way
Post by Paul Otto
to get Alpine Linux to build with that config option set, to resolve the
regression introduced by busybox 1.27.
https://git.alpinelinux.org/cgit/aports/commit/?id=
fae8e63b4df5c1052fc79ed551d442263ddcb523
William
Michael Conrad
2018-01-26 17:32:02 UTC
Permalink
Post by Denys Vlasenko
Post by Paul Otto
Read and execute commands from filename in the current shell environment
and return the exit status of the last command executed from filename. If
filename does not contain a slash, filenames in PATH are used to find the
directory containing filename. The file searched for in PATH need not be
executable. When bash is not in posix mode, the current directory is
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
But wow, learn something every day... I never knew 'source' searched
PATH at all.  I thought it just loaded a file with the same semantics as
'open()'.

This would be the danger of learning by example instead of reading the
manual.

-Mike
Cathey, Jim
2018-01-26 17:47:06 UTC
Permalink
My understanding, from years past, is that "source <file>" (or ". <file>") is _exactly_ the same as "<file>", except that it's running in _this_ shell rather than in a subshell. Thus it is able to affect environment variables that subsequent commands can inherit, etc.

If "." is not in your PATH, and you want to source a file that's right there, you have to ". ./<file>" just as you'd expect. If that's not what bash is doing, then it's wrong.

-- Jim
Michael Conrad
2018-01-26 18:01:24 UTC
Permalink
Post by Cathey, Jim
My understanding, from years past, is that "source <file>" (or ". <file>") is _exactly_ the same as "<file>", except that it's running in _this_ shell rather than in a subshell. Thus it is able to affect environment variables that subsequent commands can inherit, etc.
If "." is not in your PATH, and you want to source a file that's right there, you have to ". ./<file>" just as you'd expect. If that's not what bash is doing, then it's wrong.
I fought through the bash startup scripts almost 20 years ago in
college, and still have "source .bashrc" in my ~/.bash_profile that I've
been carrying from system to system ever since :-)  and my PATH has
never had '.' in it.  Your explanation makes perfect sense though.

-Mike
Cathey, Jim
2018-01-26 20:47:23 UTC
Permalink
Post by Michael Conrad
I fought through the bash startup scripts almost 20 years ago in
college, and still have "source .bashrc" in my ~/.bash_profile that >I've been carrying from system to system ever since :-)
and my PATH has never had '.' in it.  Your explanation makes
perfect sense though.
My understanding predates bash. :-)
But is it correct? I'd have a hard time testing one of THOSE
systems now!

-Mike
Paul Otto
2018-01-26 18:24:14 UTC
Permalink
Post by Cathey, Jim
My understanding, from years past, is that "source <file>" (or ". <file>")
is _exactly_ the same as "<file>", except that it's running in _this_ shell
rather than in a subshell. Thus it is able to affect environment variables
that subsequent commands can inherit, etc.
If "." is not in your PATH, and you want to source a file that's right
there, you have to ". ./<file>" just as you'd expect. If that's not what
bash is doing, then it's wrong.
-- Jim
Your understanding regarding how ". filename" / "source filename" is
supposed to execute commands in the file is correct, it reads and executes
commands in the *current shell* as opposed to how "./filename" runs a
script as an executable file by launching a *new shell*.

Regarding your last statement though, just because BASH doesn't adhere to
POSIX does not make it "wrong". This is particularly true when it comes to
a tool intended to emulate another tool - to change from the expected
behavior because it is believed to be "wrong" results in a tool which
incorrectly emulates BASH. BASH does many non-POSIX compliant things. It
works exactly as documented.

- Paul
Mike Frysinger
2018-01-26 18:50:02 UTC
Permalink
Post by Denys Vlasenko
Post by Paul Otto
This patch restores, and improves upon, expected behavior to BASH
compatibility which was lost beginning with 1.27.0. This was pulled into
Alpine 3.7 which, in turn was pulled into official Docker images beginning
with docker:17.12. As a result, a large number of CICD builds that use
"source filename" have broken everywhere.
Read and execute commands from filename in the current shell environment
and return the exit status of the last command executed from filename. If
filename does not contain a slash, filenames in PATH are used to find the
directory containing filename. The file searched for in PATH need not be
executable. When bash is not in posix mode, the current directory is
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
bash is its own shell. why can't it introduce its own extensions as it sees
fit ? if you want a runtime that doesn't violate POSIX standards, you can
already get that with `set -o posix` (among other ways). but it won't turn
off bash extensions that don't clash with the standard ...

if the bash-specific behavior wasn't useful, then people wouldn't request
support for them right ? :)
-mike
Denys Vlasenko
2018-01-28 18:17:57 UTC
Permalink
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
This patch restores, and improves upon, expected behavior to BASH
compatibility which was lost beginning with 1.27.0. This was pulled into
Alpine 3.7 which, in turn was pulled into official Docker images beginning
with docker:17.12. As a result, a large number of CICD builds that use
"source filename" have broken everywhere.
Read and execute commands from filename in the current shell environment
and return the exit status of the last command executed from filename. If
filename does not contain a slash, filenames in PATH are used to find the
directory containing filename. The file searched for in PATH need not be
executable. When bash is not in posix mode, the current directory is
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
bash is its own shell. why can't it introduce its own extensions as it sees
fit ?
Because a divergence is not a good thing, especially if it's gratuitous
(i.e. if a particular bashism is not adding any useful functionaluty).

Making bash "source" behavior non-standard had nothing useful in it.
Mike Frysinger
2018-01-29 05:43:45 UTC
Permalink
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
This patch restores, and improves upon, expected behavior to BASH
compatibility which was lost beginning with 1.27.0. This was pulled into
Alpine 3.7 which, in turn was pulled into official Docker images beginning
with docker:17.12. As a result, a large number of CICD builds that use
"source filename" have broken everywhere.
Read and execute commands from filename in the current shell environment
and return the exit status of the last command executed from filename. If
filename does not contain a slash, filenames in PATH are used to find the
directory containing filename. The file searched for in PATH need not be
executable. When bash is not in posix mode, the current directory is
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
bash is its own shell. why can't it introduce its own extensions as it sees
fit ?
Because a divergence is not a good thing, especially if it's gratuitous
this position makes no sense. are you saying that no shell should be allowed
to extend the syntax however it wants ? every shell out there should only be
allowed to implement POSIX and nothing else ?
Post by Denys Vlasenko
Making bash "source" behavior non-standard had nothing useful in it.
"source" is already non-standard and not specified in POSIX. so simply by
using it, your script is not POSIX compliant.
-mike
Denys Vlasenko
2018-01-29 13:41:16 UTC
Permalink
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
This patch restores, and improves upon, expected behavior to BASH
compatibility which was lost beginning with 1.27.0. This was pulled into
Alpine 3.7 which, in turn was pulled into official Docker images beginning
with docker:17.12. As a result, a large number of CICD builds that use
"source filename" have broken everywhere.
Read and execute commands from filename in the current shell environment
and return the exit status of the last command executed from filename. If
filename does not contain a slash, filenames in PATH are used to find the
directory containing filename. The file searched for in PATH need not be
executable. When bash is not in posix mode, the current directory is
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
bash is its own shell. why can't it introduce its own extensions as it sees
fit ?
Because a divergence is not a good thing, especially if it's gratuitous
this position makes no sense. are you saying that no shell should be allowed
to extend the syntax however it wants ? every shell out there should only be
allowed to implement POSIX and nothing else ?
The extensions which add some significantly useful functionality are ok.
Example: arrays.

Changes which don't really add such functionality do more harm than good.
Example: "function" keyword in bash made it possible to do this:

f() { echo "Good"; }
function g { echo "Your script is now not posix compatible,
congratu-effing-lations"; }
Mike Frysinger
2018-01-29 16:55:27 UTC
Permalink
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
This patch restores, and improves upon, expected behavior to BASH
compatibility which was lost beginning with 1.27.0. This was pulled into
Alpine 3.7 which, in turn was pulled into official Docker images beginning
with docker:17.12. As a result, a large number of CICD builds that use
"source filename" have broken everywhere.
Read and execute commands from filename in the current shell environment
and return the exit status of the last command executed from filename. If
filename does not contain a slash, filenames in PATH are used to find the
directory containing filename. The file searched for in PATH need not be
executable. When bash is not in posix mode, the current directory is
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
bash is its own shell. why can't it introduce its own extensions as it sees
fit ?
Because a divergence is not a good thing, especially if it's gratuitous
this position makes no sense. are you saying that no shell should be allowed
to extend the syntax however it wants ? every shell out there should only be
allowed to implement POSIX and nothing else ?
The extensions which add some significantly useful functionality are ok.
Example: arrays.
Changes which don't really add such functionality do more harm than good.
in general, i think you're applying 20/20 hindsight to things. it's easy to
say something is a bad idea years after the fact with experience in hand.

also, i don't think the function keyword originated in bash. the internet
suggests it originated in the korn shell and was picked up by other shells.

also, i know you know this, but POSIX isn't a spec that leads the real world.
it exists based on the corpus of existing implementations, including new
functions and features. so unless people try out new things and get others
to adopt them, then POSIX isn't going to change either. that includes trying
things that fail.
Post by Denys Vlasenko
f() { echo "Good"; }
function g { echo "Your script is now not posix compatible,
congratu-effing-lations"; }
some people like that extra syntatic sugar because it makes scanning code
and identifying functions easier (to their eyes). i've met a few people
now who argue you should always keep the "function" keyword.
-mike
Denys Vlasenko
2018-01-29 17:52:46 UTC
Permalink
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
I wish bash wouldn't introduce gratuitous standard violations.
bash is its own shell. why can't it introduce its own extensions as it sees
fit ?
Because a divergence is not a good thing, especially if it's gratuitous
this position makes no sense. are you saying that no shell should be allowed
to extend the syntax however it wants ? every shell out there should only be
allowed to implement POSIX and nothing else ?
The extensions which add some significantly useful functionality are ok.
Example: arrays.
Changes which don't really add such functionality do more harm than good.
in general, i think you're applying 20/20 hindsight to things. it's easy to
say something is a bad idea years after the fact with experience in hand.
The general observation that "compatibility is a good thing
and should not be broken just for the fun of it" is very old.
It's _good_ when you move your stuff from system to system,
from distro to distro, from one OS to another and things not break.
Or at least break not too severely.

Unfortunately, every new generation of comp-sci students
needs to learn it the hard way: by breaking it and then feeling the pain.

I still wonder how on Earth Android filesystem ended up not having /bin/sh.
No one at Google realized that people are using shell scripts
all over the Unix universe? Or they seriously did not want people
to run non-Android specific stuff on Android, and *wanted*
non-android-tailored shell scripts to fail to execute?
Mike Frysinger
2018-01-29 18:50:09 UTC
Permalink
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
I wish bash wouldn't introduce gratuitous standard violations.
bash is its own shell. why can't it introduce its own extensions as it sees
fit ?
Because a divergence is not a good thing, especially if it's gratuitous
this position makes no sense. are you saying that no shell should be allowed
to extend the syntax however it wants ? every shell out there should only be
allowed to implement POSIX and nothing else ?
The extensions which add some significantly useful functionality are ok.
Example: arrays.
Changes which don't really add such functionality do more harm than good.
in general, i think you're applying 20/20 hindsight to things. it's easy to
say something is a bad idea years after the fact with experience in hand.
The general observation that "compatibility is a good thing
and should not be broken just for the fun of it" is very old.
It's _good_ when you move your stuff from system to system,
from distro to distro, from one OS to another and things not break.
Or at least break not too severely.
again, 20/20 hindsight. you're applying this to a time when there was no
real thing as compatibility: compatible with who ? this other random project
that just started a year or two ago ? why are they better ? there were no
distros to move between, and every system was custom built. it's why POSIX
is such a mess of permission "implementation defined" cases as it tried to
bring some level of sanity to different systems.
Post by Denys Vlasenko
Unfortunately, every new generation of comp-sci students
needs to learn it the hard way: by breaking it and then feeling the pain.
or they come out with something so much better that people move away from
the previous thing entirely and it dies.
Post by Denys Vlasenko
I still wonder how on Earth Android filesystem ended up not having /bin/sh.
No one at Google realized that people are using shell scripts
all over the Unix universe? Or they seriously did not want people
to run non-Android specific stuff on Android, and *wanted*
non-android-tailored shell scripts to fail to execute?
i think it's more like you shouldn't be running shell the vast majority of
the time. systemd showed the numbers to back this up. so on a resource
constrained system (like Android phones, especially the first ones from over
a decade ago), no shell is better as it forces people to use a constrained
language. in this case, the init "exec" stuff, or a compiled language like
C or C++.
https://android.googlesource.com/platform/system/core/+/master/init/README.md
-mike
Denys Vlasenko
2018-01-30 03:00:35 UTC
Permalink
Post by Mike Frysinger
Post by Denys Vlasenko
I still wonder how on Earth Android filesystem ended up not having /bin/sh.
No one at Google realized that people are using shell scripts
all over the Unix universe? Or they seriously did not want people
to run non-Android specific stuff on Android, and *wanted*
non-android-tailored shell scripts to fail to execute?
i think it's more like you shouldn't be running shell the vast majority of
the time. systemd showed the numbers to back this up.
We should remove all shell scripts from e.g. kernel, gcc and busybox
build machinery. Because systemd. Right.
Mike Frysinger
2018-01-30 03:31:24 UTC
Permalink
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
I still wonder how on Earth Android filesystem ended up not having /bin/sh.
No one at Google realized that people are using shell scripts
all over the Unix universe? Or they seriously did not want people
to run non-Android specific stuff on Android, and *wanted*
non-android-tailored shell scripts to fail to execute?
i think it's more like you shouldn't be running shell the vast majority of
the time. systemd showed the numbers to back this up.
We should remove all shell scripts from e.g. kernel, gcc and busybox
build machinery. Because systemd. Right.
i don't know what point you're trying to make, but drop the useless
hyperbole. you asked about runtime Android, not about random dev
packages. plus i was referring to hard general data (replacing
shell scripts with compiled programs is proven benefit to boot time),
not advocating for systemd.
-mike
Denys Vlasenko
2018-01-30 12:20:50 UTC
Permalink
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
I still wonder how on Earth Android filesystem ended up not having /bin/sh.
No one at Google realized that people are using shell scripts
all over the Unix universe? Or they seriously did not want people
to run non-Android specific stuff on Android, and *wanted*
non-android-tailored shell scripts to fail to execute?
i think it's more like you shouldn't be running shell the vast majority of
the time. systemd showed the numbers to back this up.
We should remove all shell scripts from e.g. kernel, gcc and busybox
build machinery. Because systemd. Right.
i don't know what point you're trying to make, but drop the useless
hyperbole. you asked about runtime Android, not about random dev
packages.
No, I did not ask about "runtime Android", whatever that means.
Android is a Unix system, not a custom phone OS like it was the case in first
generations of phones. It can be used as a general-purpose OS:
it is possible to run anything Unixy in it. I personally
wanted to build busybox. I run compilers, editors, git and such.
It's possible.

Or rather, it is possible to run anything Unixy in it
_after_ you root it and fix the stupid decisions by Android devs
who crippled it with incompatible file system layout for no apparent
reason.

Paul Otto
2018-01-29 15:42:38 UTC
Permalink
Post by Paul Otto
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
This patch restores, and improves upon, expected behavior to BASH
compatibility which was lost beginning with 1.27.0. This was pulled
into
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
Alpine 3.7 which, in turn was pulled into official Docker images
beginning
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
with docker:17.12. As a result, a large number of CICD builds that
use
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
"source filename" have broken everywhere.
Read and execute commands from filename in the current shell
environment
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
and return the exit status of the last command executed from
filename. If
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
filename does not contain a slash, filenames in PATH are used to
find the
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
directory containing filename. The file searched for in PATH
need not be
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
executable. When bash is not in posix mode, the current
directory is
Post by Denys Vlasenko
Post by Mike Frysinger
Post by Denys Vlasenko
Post by Paul Otto
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
bash is its own shell. why can't it introduce its own extensions as
it sees
Post by Denys Vlasenko
Post by Mike Frysinger
fit ?
Because a divergence is not a good thing, especially if it's gratuitous
this position makes no sense. are you saying that no shell should be allowed
to extend the syntax however it wants ? every shell out there should only be
allowed to implement POSIX and nothing else ?
Based on my understanding of the history of these shells, BASH came up with
its syntax before the POSIX standard was ratified. So, while BASH came out
after sh, it came out *before* this "standard" was established that some
hold to so religiously.
Post by Paul Otto
Post by Denys Vlasenko
Making bash "source" behavior non-standard had nothing useful in it.
"source" is already non-standard and not specified in POSIX. so simply by
using it, your script is not POSIX compliant.
That is why, incidentally, I wrote my proposed contribution the way I did
initially. In my view, while BASH treats "source" and "." the same, POSIX
doesn't allow for "source" so why not have "source" hold to the BASH
standard and "." hold to the POSIX standard? I definitely caved too quickly
on that point, and wound up with my contribution being swallowed up into a
patch that did the exact opposite of my intent. ¯\_(ツ)_/¯
Kang-Che Sung
2018-01-29 15:54:24 UTC
Permalink
I really want to argue that there is a quite simple workaround to get the
bash 'source' behavior you need: Just append ":." to the PATH environment
variable before you run the "." command.

Or this:
source () {
PATH="$PATH:." . "$@"
}

Was there any difficulty of doing it?
Emmanuel Deloget
2018-01-29 15:56:46 UTC
Permalink
Hello,
Post by Paul Otto
Post by Mike Frysinger
Post by Denys Vlasenko
Making bash "source" behavior non-standard had nothing useful in it.
"source" is already non-standard and not specified in POSIX. so simply by
using it, your script is not POSIX compliant.
That is why, incidentally, I wrote my proposed contribution the way I did
initially. In my view, while BASH treats "source" and "." the same, POSIX
doesn't allow for "source" so why not have "source" hold to the BASH
standard and "." hold to the POSIX standard? I definitely caved too quickly
on that point, and wound up with my contribution being swallowed up into a
patch that did the exact opposite of my intent. ¯\_(ツ)_/¯
​This is probably due to the fact that many (for instance, I) expect . and
source to behave the same way :) Having them behaving differently would
somewhat violate the principle of least surprise :)

BR,

-- Emmanuel Deloget​
Mike Frysinger
2018-01-29 17:00:17 UTC
Permalink
This post might be inappropriate. Click to display it.
Bernd Petrovitsch
2018-01-28 18:51:08 UTC
Permalink
[...]
Post by Denys Vlasenko
Post by Paul Otto
Read and execute commands from filename in the current shell environment
and return the exit status of the last command executed from filename. If
filename does not contain a slash, filenames in PATH are used to find the
directory containing filename. The file searched for in PATH need not be
executable. When bash is not in posix mode, the current directory is
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
I see such begaviour more as a security problem - there are good
reasons not using "." automagically in $PATH (like DOS did .....).

Kind regards,
Bernd

PS: POSIX has some stuff in it which actually requires violation.
--
Bernd Petrovitsch Email : ***@petrovitsch.priv.at
LUGA : http://www.luga.at
Kang-Che Sung
2018-01-29 01:16:19 UTC
Permalink
On Mon, Jan 29, 2018 at 2:51 AM, Bernd Petrovitsch
Post by Bernd Petrovitsch
[...]
Post by Denys Vlasenko
Post by Paul Otto
Read and execute commands from filename in the current shell environment
and return the exit status of the last command executed from filename. If
filename does not contain a slash, filenames in PATH are used to find the
directory containing filename. The file searched for in PATH need not be
executable. When bash is not in posix mode, the current directory is
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
I see such begaviour more as a security problem - there are good
reasons not using "." automagically in $PATH (like DOS did .....).
The problem with DOS/Windows is that they prioritize "." (working directory)
over PATH when searching commands, which can cause security problems.
Bash actually considers "." last, which is less of the security threat (unless
you're setting a shell environment when user doesn't even have permission to
adjust $PATH).

For reference, here is the rationale in POSIX:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#dot

"Some older implementations searched the current directory for the [file],
even if the value of [PATH] disallowed it. This behavior was omitted from this
volume of POSIX.1-2008 due to concerns about introducing the susceptibility to
trojan horses that the user might be trying to avoid by leaving _dot_ out of
[PATH]."
Bernd Petrovitsch
2018-01-30 11:40:47 UTC
Permalink
Post by Kang-Che Sung
On Mon, Jan 29, 2018 at 2:51 AM, Bernd Petrovitsch
Post by Bernd Petrovitsch
[...]
Post by Denys Vlasenko
Post by Paul Otto
Read and execute commands from filename in the current shell environment
and return the exit status of the last command executed from filename. If
filename does not contain a slash, filenames in PATH are used to find the
directory containing filename. The file searched for in PATH need not be
executable. When bash is not in posix mode, the current directory is
searched if no file is found in PATH.
I wish bash wouldn't introduce gratuitous standard violations.
I see such begaviour more as a security problem - there are good
reasons not using "." automagically in $PATH (like DOS did .....).
The problem with DOS/Windows is that they prioritize "." (working directory)
over PATH when searching commands, which can cause security problems.
Bash actually considers "." last, which is less of the security threat (unless
you're setting a shell environment when user doesn't even have permission to
adjust $PATH).
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#dot
"Some older implementations searched the current directory for the [file],
even if the value of [PATH] disallowed it. This behavior was omitted from this
volume of POSIX.1-2008 due to concerns about introducing the susceptibility to
trojan horses that the user might be trying to avoid by leaving _dot_ out of
[PATH]."
And good so that the implicit '.' is gone.
People can add "." to $PATH anyways if they want.

And it may be less risky, if the implicit "." is at the end of $PATH
instead of the front, but (at least;-) I mistype commands often enough
and the list of aliases/shell functions a la "alias gerp=grep" keeps
growing - apparently not only for a better user interface.

Kind regards,
Bernd
--
Bernd Petrovitsch Email : ***@petrovitsch.priv.at
LUGA : http://www.luga.at
Loading...