Skip to content

Commit

Permalink
fix(_comp_expand_glob): set LC_COLLATE for the sorting order
Browse files Browse the repository at this point in the history
In sourcing the file `000_bash_completion_compat.bash` located in
/etc/bash_completion.d, we rely on the sorting order of the pathname
expansions.  However, this can be broken by locales that collates
digits after the alphabets.  We set LC_COLLATE to C and unset LC_ALL
(which might override LC_COLLATE) while keeping LC_CTYPE.
  • Loading branch information
akinomyoga committed Jun 10, 2024
1 parent 0fda821 commit ce98f68
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions bash_completion
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ _comp_expand_glob()
# result of pathname expansions.
local GLOBIGNORE="" GLOBSORT=name

# To canonicalize the sorting order of the generated paths, we set
# LC_COLLATE=C and unset LC_ALL while preserving LC_CTYPE.
local LC_COLLATE=C LC_CTYPE=${LC_ALL:-${LC_CTYPE:-${LANG-}}} LC_ALL=

eval -- "$1=()" # a fallback in case that the next line fails.
eval -- "$1=($2)"

Expand Down

5 comments on commit ce98f68

@Markospoko
Copy link

Choose a reason for hiding this comment

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

That effects in error:
-bash: warning: setlocale: LC_COLLATE: cannot change locale (): No such file or directory
-bash: warning: setlocale: LC_COLLATE: cannot change locale (): No such file or directory

@akinomyoga
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If you see the error message, it implies the locale setup in the system is broken. What are the results of the following commands in your environment?

$ declare -p LANG "${!LC_@}"
$ locale
$ locale -a | grep -Ff <(eval "locales=($(locale | sed 's/\..*//;s/^.*=//p'))"; printf '%s\n' "${locales[@]}" | sort -u)

@Markospoko
Copy link

@Markospoko Markospoko commented on ce98f68 Dec 9, 2024

Choose a reason for hiding this comment

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

I put:
export LANG="en_GB.UTF-8"
export LC_ALL="en_GB.UTF-8"
in .bash_profile and the problem vanished?
I didn't have any LC_x nor LANG wherever.
I'm doing that on macOS X.

Shouldn't LANG be ${LANG:-} instead of ${LANG-} in this line btw?

@scop
Copy link
Owner

@scop scop commented on ce98f68 Dec 10, 2024

Choose a reason for hiding this comment

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

Shouldn't LANG be ${LANG:-} instead of ${LANG-} in this line btw?

With an empty default value, the colon does not make a difference. We leave it out as a matter of style.

@akinomyoga
Copy link
Collaborator Author

@akinomyoga akinomyoga commented on ce98f68 Dec 10, 2024

Choose a reason for hiding this comment

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

I put: export LANG="en_GB.UTF-8"

Yes, setting LANG to one that exists in the system is recommended.

export LC_ALL="en_GB.UTF-8"

However, you shouldn't globally set LC_ALL, actually. The environment variable LC_ALL is used to temporarily force the locale to a specified one for a specific purpose. It disables all the other LANG and LC_* variables, which would cause problems. In the above code in bash-completion, we carefully temporarily unset LC_ALL in case a user wrongly set LC_ALL globally, but not all the locale-dependent applications carefully handle the unexpected global LC_ALL.

Please sign in to comment.