227

I just noticed that on one of my machines (running Debian Sid) whenever I type ls any file name with spaces has single quotes surrounding it.

I immediately checked my aliases, only to find them intact.

wyatt@debian630:~/testdir$ ls
'test 1.txt'  test1.txt
wyatt@debian630:~/testdir$ alias
alias ls='ls --color=auto'
alias wget='wget --content-disposition'
wyatt@debian630:~/testdir$

(picture)

Another test, with files containing single quotes in their names (also answering a request by jimmij):

wyatt@debian630:~/testdir$ ls
'test 1.txt'  test1.txt  'thishasasinglequotehere'\''.txt'
wyatt@debian630:~/testdir$ touch "'test 1.txt'"
wyatt@debian630:~/testdir$ ls
''\''test 1.txt'\'''  test1.txt
'test 1.txt'          'thishasasinglequotehere'\''.txt'

(picture)

update with new coreutils-8.26 output (which is admittedly much less confusing, but still irritating to have by default). Thanks to Pádraig Brady for this printout:

$ ls
"'test 1.txt'"   test1.txt
'test 1.txt'    "thishasasinglequotehere'.txt"

$ ls -N
'test 1.txt'  test1.txt
test 1.txt    thishasasinglequotehere'.txt

Why is this happening? How do I stop it properly?

To be clear, I myself set ls to automatically color output. It just never put quotes around things before.

I'm running bash and coreutils 8.25.

Any way to fix this without a recompile?

EDIT: Appears the coreutils developers chose) to break with the convention and make this the global default.


UPDATE - October 2017 - Debian Sid has re-enabled the shell escape quoting by default. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877582

And at the bottom of the reply chain to the previous bug report, "the change was intentional and will remain." https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=813164#226

I thought this had already been settled, but apparently it was just reverted so that the "stable" Debian branch could keep its "feature freeze" while getting the other fixes, etc. from the newer version. So that's a shame (in my opinion).

UPDATE: April 2019: Just found a spurious bug report in PHP that was caused by this change to ls. When you're confusing developers and generating false bug reports, I think it might be time to re-evaluate your changes.

Update: Android toybox ls is now doing something similar to this but with backslashes instead of quotes. Using the -q option makes spaces render as 'question mark characters' (I have not checked what they are, since they're obviously not spaces), so the only fix I have found so far without rooting the device in question is to add this to a script and source it when launching a shell. This function makes ls use columns if in a terminal and otherwise print one-per-line, while tricking ls into printing spaces verbatim because it's running through a pipe.

ls() {
    # only way I can stop ls from escaping with backslashes
    if [ -t 1 ]; then
        /system/bin/ls -C $@ |cat
    else
        /system/bin/ls $@ |cat
    fi
}
21
  • 22
    Yet another reason why not parser the ls command.
    – jimmij
    Jan 30 '16 at 7:27
  • 14
    It looks odd but if it's only enabled when printing to a terminal it makes sense. You can see clearly that you have a file 'test 1.txt' rather than a file 'test' and another '1.txt'. Try ls | cat and see if it goes away. If I had a time machine, I would go back to Bell Labs ~1970 and try to convince Ken Thompson that allowing space in file and directory names is a bad idea. :-P Jan 30 '16 at 9:06
  • 7
    When I first saw this, I freaked out, thinking that one of my scripts had gone awry and renamed all my files to '*'. I guess I'll go around adding ls aliases to all my machines to get rid of it... Feb 12 '16 at 18:57
  • 15
    @LimitedAtonement, as pointed out by Lekensteyn, you can do this with an environment variable QUOTING_STYLE=literal rather than an alias. (I guess it's a matter of taste, but I prefer the variable.)
    – LSpice
    Feb 15 '16 at 23:15
  • 4
    @BjornMunch there are two solutions to the issue of telling whether it is one file or two: 1) look for how the columns are being drawn and it is fairly obvious. 2) list one item per line. Both of those look better and clearer than the mangling with single quotes.
    – Wyatt Ward
    Feb 23 '16 at 14:52
146

Preface: While it may be quite satisfying to upvote an answer such as this and call it a day, please be assured that the GNU coreutils maintainers do not care about SO answer votes, & that if you actually want to encourage them to change, you need to email them as this answer describes.


Update 2019:
Sometime this past year the maintainers have doubled-down and now offer to any bug-coreutils@gnu.org reports about this issue only a boilerplate response pointing to an incredibly long page on their website listing problems people have with this change that they have committed themselves to ignoring.
The unceasing pressure from bug-coreutils@gnu.org reports has clearly had an effect, forcing the generation of this immense & absurd page, and potentially reducing the number of maintainers willing to deal with the problem to only one.
When this many people consider a thing a bug, then it's a bug whether maintainers disagree or not.
Continuing to email them remains the simplest way to encourage change.


"Why is this happening?"

Several coreutils maintainers decided they knew better than decades of de facto standards.


"How do I stop it properly?"

http://www.gnu.org/software/coreutils/coreutils.html:

Bug Reports

If you think you have found a bug in Coreutils, then please send as complete a bug report as possible to <bug-coreutils@gnu.org>, and it will automatically be entered into the Coreutils bug tracker. Before reporting bugs please read the FAQ. A very useful and often referenced guide on how to write bug reports and ask good questions is the document How To Ask Questions The Smart Way . You can browse previous postings and search the bug-coreutils archive.

Distros that have already reverted this change:

Distros unaffected:

  • openSUSE (already used -N)

"Any way to fix this without a recompile?"

Proponents would have you...

get back to the old format by adding -N to their ls alias

…on all of your installs, everywhere, for the remainder of eternity.

23
  • 20
    The change was proposed on the mailing list and agreed by three coreutils maintainers to be a net benefit. We're entirely open to constructive arguments about this. This is open source after all, we don't mean to dictate, only to improve things. Please feel free to respond in the coreutils thread at lists.gnu.org/archive/html/coreutils/2016-02/msg00000.html (BTW the way, there was a constructive suggestion to improve on one of the aesthetic disadvantages mentioned there, by adding a space to improve alignment) Feb 15 '16 at 20:46
  • 42
    @PádraigBrady Updated answer. Seeing loads of denial in your coreutils thread, though. The bottom line is you are creating more work for people, and you're doing it in the name of an OS that is a clone of an OS from 1970. If people want something different, they will opt into it. Feb 17 '16 at 22:21
  • 52
    @PádraigBrady This change has caused me annoyance and wasted several hours trying find a cause and a solution. I don't mean to be negative - I'm just sharing another persons viewpoint! Modifying core behaviour has huge implications..
    – mafrosis
    Mar 16 '16 at 16:15
  • 65
    As someone who's used *nix systems for 30 years, I find gratuitous changes like this to be quite annoying. They break long-standing scripts, for one thing. They also violate the Principle of Least Astonishment. "Opt-in" should've been the default here, as noted above. Apr 7 '16 at 0:01
  • 33
    @PádraigBrady That's still not the way to push such changes. It'd have been way more constructive to have that behaviour opt-in instead of active by default. It also falsely hints this is how file names are stored, in short with ls what you see no longer is how it's stored. That feature should be optional, not the default.
    – user86969
    May 26 '16 at 13:19
127

You can chose quoting style:

ls --quoting-style=literal

The same as:

ls -N

or:

QUOTING_STYLE=literal ls

Make it an alias, or set export QUOTING_STYLE=literal in your .bashrc to achieve pre-8.25 behavior.

15
  • 17
    seems a bit weird I have to do that to get normal unix-y behavior. Also, I want the old default. I don't think escaping was the old default - I think it printed exactly what was actually there.
    – Wyatt Ward
    Jan 30 '16 at 15:58
  • 11
    For pre-8.25 behavior, use export QUOTING_STYLE=literal in your bashrc.
    – Lekensteyn
    Jan 31 '16 at 11:07
  • 3
    or use -N, it seems. I'm just compiling my own version since I already have a personal repository set up.
    – Wyatt Ward
    Jan 31 '16 at 15:12
  • 2
    @LSpice I have edited the post to use literal instead of escape (I believe that @cuonglm just wanted to show how to change the style, not specifically targetting the escape style).
    – Lekensteyn
    Feb 16 '16 at 10:31
  • 8
    This answer deserves more upvotes. It straightly addresses what the questioner asked avoiding a bureaucratic answer. Indeed, the environment variable approach seems pretty elegant. (I personally prefer the new behavior as it favors a more efficient C&P action), yet, ls is clever enough to behave the old way when a redirection is used, so no harm to scripts that uses ls' output.
    – Marcelo
    Nov 24 '17 at 1:17
52

A few points about the change.

  • It was introduced in coreutils v8.25, and alignment improved in v8.26
  • It only happens when outputting to terminals so doesn't break scripts
  • It disambiguates the output for users for files containing whitespace
  • It sanitizes output so it is safe to copy and paste
  • Output is now always valid to copy and paste back to shell
  • Users can get back to the old format by adding -N to their ls alias
28
  • 8
    my last example isn't ambiguous? Perhaps not - but it's certainly confusing and takes more time to decipher. I think it's an awful change (no offense intended to you). Thanks for the alias tip though.
    – Wyatt Ward
    Jan 30 '16 at 15:58
  • 4
    I agree w/ @Wyatt8740 - this is not a good idea. At least the default ? substitution is officially acknowledged - this is just off the wall. You are adding characters to filenames which are not in the filenames in the output of a utility which is supposed to list filenames. Doing this to shell-eval-safe said filenames is, as I think, misguided. Unless you do it robustly and shell-quote any possible shell-quotes in your output then you're only trading a bad rare case for a worse one and distorting your output for the sake of it. please do the standard thing whenever possible.
    – mikeserv
    Feb 5 '16 at 16:55
  • 13
    my apologies - apparently you are safely shell-quoting the shell-quotes at least. i still do not like it. the options are fine - but altering the very well-specified default behavior of a decades-old unix core utility in such a way that diminishes its veracity can only be a bad idea.
    – mikeserv
    Feb 5 '16 at 17:03
  • 6
    "Users can get back to the old format by adding -N to their ls alias" Users could already set QUOTING_STYLE=shell if they wanted this output. Changing the default has only caused more work for distros.
    – bobpaul
    Mar 6 '16 at 17:51
  • 7
    @PádraigBrady I'm grateful for the work you do in maintaining coreutils. But changing the default formatting for ls was a mistake. The simple fix is to make the new formatting "opt-in". Distros already contain .bashrc files that typically tweak the behavior of ls and other coreutils, adding colors, etc. That would be the right place to enable the new formatting for the ones that want it.
    – Roger Dahl
    Jul 20 '18 at 16:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.