2024年5月14日(火) 15:09 Martin D Kealey <mar...@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. * 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.