Why does ls wrap some filenames in single quotes?

I've noticed that when I do ls in a terminal, some filenames are wrapped in single quotes and some aren't.

I don't like the way this looks as I prefer my terminal outputs to be nice and uniform. What causes this functionality, and is it possible to safely disable it?

enter image description here


Solution 1:

Why ls wraps some filenames in single quotes

ls wraps single quotes around filenames with spaces in them, for the purpose of allowing the filenames to be safely copied, used in a script or piped through another command.

enter image description here

This was a highly unpopular feature introduced to version 8.25 of the GNU coreutils package as recently as 2016, by a consensus of just three developers.

Arguments cited by critics of the change include that it makes the output of ls look considerably more unsightly, unnecessarily diverges from nearly half a century of Unix tradition, and due to the way it was implemented (opt-out instead of opt-in) breaks compatibility with long-standing existing scripts and utilities.

Because the feature was introduced to the coreutils package - which virtually every Linux distribution depends on and which ls is a part of - the change affects every Linux or Linux-like system imaginable, from Arch Linux to Cygwin.

In the case of Debian and Debian-derived distros like Ubuntu, the change was at some point reverted after considerable protest, before being once again reinstated in October 2017.

As this answer makes clear, the best way to register your disappointment at this change would be to contact the coreutils developers directly via a bug report and (politely) make the argument that they've made a huge mistake. As per the open source ethos, a critical mass of users respectfully but adamantly insisting that the way ls used to behave be properly reinstated should in theory be enough to convince the coreutils developers to listen to the Linux community.


Restoring ls' pre-version 8.25 behaviour

In the more short-term, pragmatic sense, there are several ways you can restore ls' pre-version 8.25 behaviour of leaving all output intact. Below are three methods to doing so for the bash shell.

Use the QUOTING_STYLE environment variable

Find your ~/.bashrc file in your HOME folder (/home/yourusername), and add the following line to it:

export QUOTING_STYLE=literal

Save the file, and the change should apply immediately to all new bash terminals that you open.

You can also run source ~/.bashrc to have the changes be pushed to any terminal windows that were open at the time of making the change.

Create an alias to ls -N

If you prefer aliases to environment variables, you can also create an alias in .bashrc that uses 8.25's new -N switch. From ls --help:

-N, --literal print entry names without quoting

To do this, add the following line to your ~/.bashrc file and save it:

alias ls="ls -N"

Run source ~/.bashrc to have the new change be pushed to all open terminals.

For the current run only: use the -N command-line switch

If you prefer coreutils' new default behaviour but want to bypass it temporarily, you can also use the -N switch directly in a command:

ls -N