shell: reconcile language and sort behaviour

Hi

Don't know if this is a dummy question, but let's give it a try.

I yesterday had a problem with undefined behaviour in the sort shell command (I'm using bash), leading to different sort orders without apparent reasons. I resolved this by typing

export LC_ALL="C"
export LC_COLLATE="C"
export LC_CTYPE="C"

and adding this to my .bash_profile as well.

The language is still set to english :

[jos@faba ~]$ echo $LANG
en_US.UTF-8

But now, the shell doesn't recognize special characters anymore, like accented ones (I've lots of them : although my system is in english, I'm in France so I've lots of accents in my filenames).
Even in english text, non-recognized characters do appear (for instance "man rpm" gives "<E2><80><99>" characters).

My question : is it "either-or", i.e. either correct sorting behaviour or correct character handling, or is there a way to have both behave correctly ?

Thanks in advance
jos

Do not set LC_* in your profile. Just run the sort command in a different environment, when needed:

LC_COLLATE=C sort ...

or

LC_ALL=C sort ...

Interesting possibility.
Can one set both LC_COLLATE and LC_ALL this way ?

LC_COLLATE="C" LC_ALL="C" sort ...

??

I found that only setting one of them still leeds to unpredictable sort results.

If this is possible, I could just create a sort alias, I imagine ?

In that case use:

LC_ALL=C sort ...

... and you'll get the expected result.

The multiple assignment should work too, though ...

% env | grep ^var
%                                       
% var1=a var2=b sh -c 'env | grep ^var' 
var1=a
var2=b

You could create a function:

clocale_sort() {
  local LC_COLLATE=C LC_LANG=C
  sort ...
  }

Notice that the local keyword is not standard (some shells use typeset, other do not have local variables (?)).

Or you can just run the command in a "isolated" environment (in a sub-shell):

(
  LC_LANG=C LC_COLLATE=C
  export LC_LANG LC_COLLATE
  sort ..
  )

No, I don't, only LC_ALL is not sufficient ... struggled with that yesterday :slight_smile:

So this seems to work :

alias csort="LC_ALL=C LC_COLLATE=C LC_CTYPE=C sort"

I'm not sure why I should create a function or isolated environment ... nor how to do this exactly, never done before.

Thanks !

If the alias is sufficient, use it (the functions are just more flexible and powerful).