history-search-backward clobbers history

2024-06-19 Thread Andreas Schwab
$ 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

2024-06-19 Thread Will Allan
> 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

2024-06-19 Thread Léa Gris

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-06-19 Thread Koichi Murase
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

2024-06-19 Thread Will Allan
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

2024-06-19 Thread konsolebox
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

2024-06-19 Thread konsolebox
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

2024-06-19 Thread Will Allan via Bug reports for the GNU Bourne Again SHell
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

2024-06-19 Thread Oğuz
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