Skip to content

bash version detection is locale independent#1942

Merged
davidism merged 1 commit into
pallets:8.0.xfrom
janLo:patch-1
Jul 3, 2021
Merged

bash version detection is locale independent#1942
davidism merged 1 commit into
pallets:8.0.xfrom
janLo:patch-1

Conversation

@janLo
Copy link
Copy Markdown
Contributor

@janLo janLo commented Jun 1, 2021

The BASH_VERSION variable holds the bash version number in a much
better consumable and especially locale independent format than the
--version flag.

This fixes #1940

Checklist:

  • Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
  • Add or update relevant docs, in the docs folder and in code.
  • Add an entry in CHANGES.rst summarizing the change and linking to the issue.
  • Add .. versionchanged:: entries in any relevant code docs.
  • Run pre-commit hooks and fix any issues.
  • Run pytest and tox, no tests failed.

@davidism davidism added this to the 8.0.2 milestone Jun 1, 2021
@davidism
Copy link
Copy Markdown
Member

davidism commented Jun 1, 2021

Please rebase to 8.0.x and add a changelog entry.

@davidism davidism changed the base branch from main to 8.0.x June 1, 2021 18:57
@janLo
Copy link
Copy Markdown
Contributor Author

janLo commented Jun 1, 2021

Please rebase to 8.0.x and add a changelog entry.

Done.

output = subprocess.run(["bash", "--version"], stdout=subprocess.PIPE)
match = re.search(r"version (\d)\.(\d)\.\d", output.stdout.decode())
output = subprocess.run(
["bash", "-c", "echo ${BASH_VERSION}"], stdout=subprocess.PIPE
Copy link
Copy Markdown

@igrr igrr Jun 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that this does not always return the version of bash where autocompletion has been invoked from.

Here's an example, taken from one macOS system:

$ which -a bash
/usr/local/bin/bash
/bin/bash
$ help | head -1
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
$ bash -c 'echo ${BASH_VERSION}'
4.4.23(1)-release
$ echo $BASH_VERSION
3.2.57(1)-release

Here, /bin/bash is the OS-provided bash 3.2.57, while /usr/local/bin/bash is bash 4.4.23 installed using Homebrew. The user profile is configured with /bin/bash as the login shell.

I don't see a good way to resolve this issue other than to tell the user that such setup is "broken". I'm mentioning it anyway in case someone else has an idea.

(This PR is still an important improvement over the previous bash --version approach, which also suffers from the issue I mentioned. So this comment shouldn't be considered as a blocker for merging the PR.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If BASH_VERSION is available in the env, then couldn't we look at that directly?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately BASH_VERSION is not exported by default, so while

$ echo ${BASH_VERSION}
4.4.23(1)-release

works,

$ python -c 'import os; print(os.environ.get("BASH_VERSION"))'
None

doesn't. This can be worked around by doing export BASH_VERSION before invoking click for autocompletion, but I think this would be a breaking change.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the current code has the very same problem, as you initially mentioned @igrr, as it also just calls the first bash in $PATH.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with that and with your proposed solution @janLo, I only mentioned this (extra) issue in case anyone looking at this PR comes up with a way to deal it.

@sscherfke
Copy link
Copy Markdown
Contributor

sscherfke commented Jun 24, 2021

I would change it to that for now:

        output = subprocess.run(["bash", "--version"], stdout=subprocess.PIPE)
        match = re.search(r"(\d+)\.(\d+)\.\d+", output.stdout.decode())

This solves the locale dependent spelling of version ans also adds support for multi-digit versions (e.g. 5.12.23). Since this still uses bash --version, it won’t introduce new issues.

So while this may not be the perfect solution, it will certainly improve the current state. :)

@janLo
Copy link
Copy Markdown
Contributor Author

janLo commented Jun 25, 2021

Why not use the version variable. This would completely avoid future surprises that always happen when one tries to parse data out of human readable descriptions one does not control.

The variable is at least clearly defined:

BASH_VERSION
The version number of the current instance of Bash.

(From https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html)

The `BASH_VERSION` variable holds the bash version number in a much
better consumable and especially locale independent format than the
`--version` flag.
@davidism davidism changed the title fix: make bash version detection locale independ bash version detection is locale independent Jul 3, 2021
@davidism davidism merged commit 976d25b into pallets:8.0.x Jul 3, 2021
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Jul 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bash version detection fails with certain locales

4 participants