history-search-backward clobbers history
$ printf 'echo 1234\necho 2345\necho 3456\n' > history $ HOME=$PWD HISTFILE=history TERM=xterm bash --norc -i <<<$'\20\eb1\e[5~\nhistory\n\20\20\eb2\e[5~\nhistory' bash-5.3$ echo 1234 1234 bash-5.3$ history 1 echo 1234 2 echo 2345 3 echo 13456 4 echo 1234 5 history bash-5.3$ echo 2345 2345 bash-5.3$ history 1 echo 1234 2 echo 2345 3 echo 13456 4 echo 21234 5 history 6 echo 2345 7 history bash-5.3$ exit $ cat history echo 1234 echo 2345 echo 3456 echo 21234 history echo 2345 history -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
Re: proposed BASH_SOURCE_PATH
> Not sure how common but this is what makes sense. Or name sourceables > foo.sh, bar.sh and executables foo, bar so they don't clash and source with > `${BASH_SOURCE%/*}' prepended to PATH and it'll work fine. > > This feature request sounded promising at first, it feels like > bike-shedding now. I think this is exactly why this feature is necessary. Unless I am misunderstanding, simply prepending `${BASH_SOURCE%/*}' to a sourced path will not work in all cases. For example, when executing the main script directly inside the script directory (e.g. `bash main.sh`) you would end up with an invalid path (e.g. main.sh/../lib/foo.sh). To solve such a seemingly simple problem when first introduced to Bash, I turned to StackOverflow. Note this question has hundreds of answers of varying complexity with thousands of up and downvotes. Yikes! https://stackoverflow.com/questions/59895/how-do-i-get-the-directory-where-a-bash-script-is-located-from-within-the-script Since I find the accepted answer to be overly complex for my needs, I usually just do this: declare -r SCRIPT_DIR="$(dirname -- "${BASH_SOURCE[0]}")" source -- "${SCRIPT_DIR}/../lib/foo.sh" source -- "${SCRIPT_DIR}/../lib/bar.sh" ... But, I still don’t like it. I have to start off each script with a slow command substitution (subshell) which introduces a variable that I don’t really want, but it’s too slow to do this repeatedly: source -- "$(dirname -- "${BASH_SOURCE[0]}")/../lib/foo.sh" source -- "$(dirname -- "${BASH_SOURCE[0]}")/../lib/foo.sh" ... I would love to be able to do this for efficiency and readability (see below). This would prevent future users from having to sift through hundreds of faulty StackOverflow answers like I did. source -- "${BASH_SOURCE_PATH}/../lib/foo.sh" source -- "${BASH_SOURCE_PATH}/../lib/bar.sh" ... -Will
Re: proposed BASH_SOURCE_PATH
Le 19/06/2024 à 22:04, Will Allan écrivait : Since I find the accepted answer to be overly complex for my needs, I usually just do this: declare -r SCRIPT_DIR="$(dirname -- "${BASH_SOURCE[0]}")" source -- "${SCRIPT_DIR}/../lib/foo.sh" source -- "${SCRIPT_DIR}/../lib/bar.sh" ... But, I still don’t like it. I have to start off each script with a slow command substitution (subshell) which introduces a variable that I don’t really want, but it’s too slow to do this repeatedly: source -- "$(dirname -- "${BASH_SOURCE[0]}")/../lib/foo.sh" source -- "$(dirname -- "${BASH_SOURCE[0]}")/../lib/foo.sh" Look like you did not find a proper answer there. Here is one simple that involve no sub-shell at all and does exactly what your sub-shell version does. declare -r SCRIPT_DIR=${BASH_SOURCE[0]%/*} Now indeed this does not solve symbolic links and to do this, you need a sub-shell and it is not system agnostic anymore. realSource=$(realpath -- "${BASH_SOURCE[0]}") && realScriptDir=${realSource%/*} -- Léa Gris
Re: proposed BASH_SOURCE_PATH
2024年6月20日(木) 5:47 Léa Gris : > Look like you did not find a proper answer there. Here is one simple > that involve no sub-shell at all and does exactly what your sub-shell > version does. > > declare -r SCRIPT_DIR=${BASH_SOURCE[0]%/*} This doesn't work as explained by Will. BASH_SOURCE doesn't contain a slash when the script is specified as e.g. `bash a.sh' or `source a.sh'. > [...] it is not system agnostic anymore. POSIX 2024 containing realpath(1) was just published, though I'm not sure when/whether it will be available in very old systems. -- Koichi
Re: proposed BASH_SOURCE_PATH
Yes, that's precisely my point. It suddenly becomes more complex and bug prone than at first glance. To do it without a subshell, I need something like this boilerplate at the top of each of my main scripts: if [[ "${BASH_SOURCE[0]}" == */* ]]; then SCRIPT_DIR="${BASH_SOURCE[0]%/*}" else SCRIPT_DIR="." fi -Will On Wednesday, June 19, 2024 at 02:08:27 PM PDT, Koichi Murase wrote: 2024年6月20日(木) 5:47 Léa Gris : > Look like you did not find a proper answer there. Here is one simple > that involve no sub-shell at all and does exactly what your sub-shell > version does. > > declare -r SCRIPT_DIR=${BASH_SOURCE[0]%/*} This doesn't work as explained by Will. BASH_SOURCE doesn't contain a slash when the script is specified as e.g. `bash a.sh' or `source a.sh'. > [...] it is not system agnostic anymore. POSIX 2024 containing realpath(1) was just published, though I'm not sure when/whether it will be available in very old systems. -- Koichi
Re: proposed BASH_SOURCE_PATH
On Thu, Jun 20, 2024 at 4:47 AM Léa Gris wrote: > realSource=$(realpath -- "${BASH_SOURCE[0]}") && > realScriptDir=${realSource%/*} `realScriptDir=$(realpath -m "${BASH_SOURCE}/..") || exit` is simpler if you don't care about versions of realpath not supporting `-m`. It is mostly convenient if you only need to load a single script. For example: source "$(realpath -m "${BASH_SOURCE}/../../lib/script.bash")" || exit -- konsolebox
Re: proposed BASH_SOURCE_PATH
On Thu, Jun 20, 2024 at 4:05 AM Will Allan wrote: > But, I still don’t like it. I have to start off each script with a slow > command substitution (subshell) which introduces a variable that I don’t > really want, but it’s too slow to do this repeatedly: I agree. > source -- "${BASH_SOURCE_PATH}/../lib/foo.sh" You misunderstood the use of BASH_SOURCE_PATH though. It's proposed to be an alternative to PATH which is only respected by source. I suggest another name. And that is BASH_SOURCE_REAL. Alternatively, have BASH_SOURCE always produce real physical paths either by default or through a shopt. Any additional feature that doesn't allow loading a script relative to the caller without external help is practically useless. -- konsolebox
Re: proposed BASH_SOURCE_PATH
Thanks for clarifying! I wondered if I was missing something, but kept seeing `${BASH_SOURCE[0]/%/*}` suggested in the thread, which I pointed out is flawed. I guess what I want is a "BASH_SOURCE_DIR" variable or something like it, mainly to avoid the boilerplate, variable, and/or command substitution in each of my main scripts. Note that ShellCheck uses a similar SCRIPTDIR to help locate sourced files relative to the main script: https://github.com/koalaman/shellcheck/issues/1577 -Will On Wednesday, June 19, 2024 at 03:13:59 PM PDT, konsolebox wrote: On Thu, Jun 20, 2024 at 4:05 AM Will Allan wrote: > But, I still don’t like it. I have to start off each script with a slow > command substitution (subshell) which introduces a variable that I don’t > really want, but it’s too slow to do this repeatedly: I agree. > source -- "${BASH_SOURCE_PATH}/../lib/foo.sh" You misunderstood the use of BASH_SOURCE_PATH though. It's proposed to be an alternative to PATH which is only respected by source. I suggest another name. And that is BASH_SOURCE_REAL. Alternatively, have BASH_SOURCE always produce real physical paths either by default or through a shopt. Any additional feature that doesn't allow loading a script relative to the caller without external help is practically useless. -- konsolebox
Re: proposed BASH_SOURCE_PATH
On Wednesday, June 19, 2024, Will Allan wrote: > I think this is exactly why this feature is necessary. Unless I am > misunderstanding, simply prepending `${BASH_SOURCE%/*}' to a sourced path > will not work in all cases. For example, when executing the main script > directly inside the script directory (e.g. `bash main.sh`) you would end up > with an invalid path (e.g. main.sh/../lib/foo.sh). > What I'm saying there is name it main and execute like `./main'. I'm not against having a variable that's automatically populated with the parent directory of the source script, I just don't need it and it wasn't what we were discussing. -- Oğuz