Skip to content

human readable sizes ignore the locale decimal separator, which breaks du -h | sort -h #14232

Description

@desvaters

Note: written with AI assistance because English is not my first language. All commands were run and verified by me.

du -h, ls -h and numfmt --to=iec always print the fraction with a period, no matter what LC_NUMERIC says. GNU coreutils prints the locale decimal separator instead. Under de_DE.UTF-8:

output of GNU 9.11 uutils 0.10.0
du -h 4,0K 4.0K
ls -lh 4,0K 4.0K
numfmt --to=iec 4096 4,0K 4.0K

sort -h reads the decimal separator from the locale correctly and in the same way GNU does. So the two halves of du -h | sort -h disagree about what a period means, and the pipeline that is probably the main use of -h produces a wrong order.

Reproduce:

mkdir -p tree/a && head -c 4000 /dev/zero > tree/a/f
LC_NUMERIC=de_DE.UTF-8 du -h tree/a
LC_NUMERIC=C du -h tree/a

uutils prints 4.0K in both cases. GNU prints 4,0K and 4.0K.

The follow on effect:

printf '32K\n4.0K\n40K\n76K\n8.0K\n288K\n' > sizes.txt
LC_NUMERIC=de_DE.UTF-8 sort -h sizes.txt | tr '\n' ' '

Result 32K 4.0K 40K 76K 8.0K 288K.

To be clear about where I think the bug is not: sort -h looks correct. GNU
sort -h misorders the same period input under the same locale, and orders the
comma input correctly. Both implementations agree, so sort is doing what it
should. The output side is what differs from GNU.

df -h may well have the same problem, but on my system every value there is a
whole number, so I could not tell.

Versions: uutils 0.10.0 and 0.8.0 (the version shipped in Ubuntu 26.04), same
result in both. Compared against GNU coreutils 9.11 from conda-forge, since
Ubuntu 26.04 no longer ships GNU binaries.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions