bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: proposed BASH_SOURCE_PATH


From: Peng Yu
Subject: Re: proposed BASH_SOURCE_PATH
Date: Tue, 14 May 2024 23:13:15 -0500

On Tue, May 14, 2024 at 3:35 AM Koichi Murase <myoga.murase@gmail.com> wrote:
>
> 2024年5月14日(火) 15:09 Martin D Kealey <martin@kurahaupo.gen.nz>:
> > 1. I therefore propose that where a relative path appears in
> > BASH_SOURCE_PATH, it should be taken as relative to the directory
> > containing $0 (after resolving symlinks), rather than relative to $PWD.
> >
> > As an interim step until that's implemented, please ignore any relative
> > entries in BASH_SOURCE_PATH, so that users who really want the cwd in
> > BASH_SOURCE_PATH get used to writing $PWD or /proc/self/cwd instead.
>
> I totally agree that we should have a way to specify the files in
> subdirectories by the path relative to the current script file.

I currently use something like this to source script files relatively.

declare -g -A __sourced__files__
__sourced__files__[$BASH_SOURCE]=$(realpath "$BASH_SOURCE")
# This is to ensure to the relative path is to the actual bash file
instead of a symlink to the bash file.
source 
"${__sourced__files__[$BASH_SOURCE]%/*}/dirname1/dirname2/${BASH_SOURCE##*/}"
# My convention is that the file sourced in the subdirectory has the
same filename as the parent file.
# The difference between them are expressed in the directory path,
i.e., dirname1/dirname2

My concern with adding too many features in bash is that it may have a
maintenance problem and backward compatibility issues.

Python has this problem. Python2 was good, but they introduced python3
which supposedly to make it better. But python3 introduced too many
problems. One problem is it is very difficult to import a python file
at an arbitrary location in Python3. There are too many redundant
features in Python 3, it is unclear which one is more stable then the
other. Sometimes, a feature is removed in newer version of Python
which breaks my programs that used to work. This increases maintenance
costs.

In this case, my above method works fine for many years. It sounds to
me like adding a new feature for a relative source is unnecessary.

> * One concern with treating relative paths relative to the current
> script location is that the user might put `.' in BASH_SOURCE_PATH to
> mean the current directory. I don't think it is a good practice, but I
> anticipate that users expect that. For example, one can observe the
> default values of PATH [1] and BASH_LOADABLES_PATH [2] in the Bash
> codebase. It explicitly contains `.' to mean the current working
> directory. It is very confusing that `.' in BASH_SOURCE_PATH points to
> the script location ($(dirname ${BASH_SOURCE[0]})), while `.' in PATH
> and BASH_LOADABLES_PATH points to the current working directory
> ($PWD).
>
> [1] 
> https://git.savannah.gnu.org/cgit/bash.git/tree/config-top.h?h=devel&id=b3d8c8a4e7c5417d986f93f646ea740cb13c08d7#n61
> [2] 
> https://git.savannah.gnu.org/cgit/bash.git/tree/config-top.h?h=devel&id=b3d8c8a4e7c5417d986f93f646ea740cb13c08d7#n78
>
> One solution might be to treat `.' as a special case to mean $PWD, and
> the other relative paths would mean the path relative to the script
> location. However, the problem is that it is confusing that the base
> location changes depending on its form. In particular, the difference
> in the behavior between `.' and `..' would be very confusing.
>
> Another solution would be to introduce a special name to mean the
> current script location. For example, we could introduce a tilde
> expansion to mean the current script location since the only expansion
> processed in `find_path_in()' and related functions is the tilde
> expansion. We already have ~+ and ~+N (equivalently, ~N) to mean
> ${DIRSTACK[N]}. Similarly, we can have e.g. ~@  and ~@N to mean
> $(dirname ${BASH_SOURCE[N]}). This can also be useful outside
> BASH_SOURCE_PATH since determining the directory name of a path isn't
> just ${path%/*} and one needs to care about edge cases to properly do
> that.
>
> * Another point to discuss is whether we should resolve the symbolic
> links. Maybe it's just fine to resolve the symbolic links fully (as
> suggested), but another possibility can be to search all the
> directories appearing in the intermediate steps of the link
> resolution.
>
> > 2. Search BASH_SOURCE_PATH when any relative path is given, not just a path
> > that lacks a '/', so that libraries can be organized into subdirectories.
>
> I agree. I actually thought about raising the discussion about this
> after the current patch set is merged.
>
> > 3. To avoid accidentally loading a script rather than a library, while
> > searching BASH_SOURCE_PATH, ignore any files that have exec permission,
> > inverting the check normally made for executables in PATH. This would keep
> > executables and libraries functionally separate, even if they're commingled
> > in the same directories.
>
> I disagree with this. Since the original intent of having
> BASH_SOURCE_PATH would be to have the list of directories that do not
> contain files not intended to be sourced, I don't see a reason to
> perform additional filtering. I generally think that applications
> shouldn't give a new meaning of the executable permission of files for
> a purpose different from the original one. They may conflict.
>
> > Yes I know that some folk think it's occasionally useful to have a single
> > file that operates as both, but (a) new features should default to the
> > "safest" mode of operation, (b) this isn't python and so that's pretty rare
> > in practice,
>
> How did you conclude that it's rare? Phi mentioned it. I also have a
> script that operates as both. Furthermore, it's actually a recommended
> practice by the bpkg manager [3].
>
> [3] https://github.com/bpkg/bpkg?tab=readme-ov-file#packaging-best-practices
>
> For a script file with both usages, I think one wants to put symbolic
> links to the file in PATH and BASH_SOURCE_PATH. In such a situation,
> the suggested non-executable requirement conflicts with the
> requirement for executable files. Do we prohibit the existence of such
> a script? Or do we request to make an actual copy or a hard link to
> the file (which I think is a bit harder to manage the consistency)? I
> think these are unnecessary requirements.
>
> > 4. When using "source -i", if BASH_SOURCE_PATH is unset or empty, it's
> > taken as equivalent to '.', so that it's useful to write "source -i
> > ../lib/foo.bash" in a script at "$X/bin/bar" to load "$X/lib/foo.bash".
>
> I currently have no particular opinion on this. Maybe I need to think
> about it later.
>


-- 
Regards,
Peng



reply via email to

[Prev in Thread] Current Thread [Next in Thread]