2

I need to create a file named *'test'*

If I write touch \'test\'

ls shows 'test'

But if I write touch \*\'test\'\*

ls now shows *'\''test'\''*

What's the trick ? Can someone explain me what I did wrong ?

My OS is Ubuntu 20.04

Shoopi
  • 31
  • 2
    You do not need to create file with such name. This (if succeed) will be call for troubles. – Romeo Ninov Feb 14 '24 at 18:38
  • 3
    That latter output, *'\''test'\''*, doesn't make sense, and it's inconsistent with the first one. So, what you did wrong appears to be that you didn't show the exact commands you used, and their exact output in the question here. (Note that it's not just for us, it's also important for you as the user of the tools in question to read exactly what they output, esp. when you're playing with funky stuff like this) – ilkkachu Feb 14 '24 at 19:03
  • 2
    It's unclear whether you need to create a fie with a particular name, or whether you need ls to create a specific output. – Kusalananda Feb 14 '24 at 20:42

3 Answers3

6

The problem is that GNU ls tries to be helpful by outputting odd filenames in an unambiguous quoted format, similar to how they could be entered in the shell to get the same name.

Sometimes it helps, and sometimes it just adds confusion. To switch off the feature, either set the controlling environment variable:

export QUOTING_STYLE=literal
ls

Or use the corresponding command line flag:

ls --quoting-style=literal

or the shorter ls -N.

You can create file names with strange characters by quoting them:

touch "*'test'*"                       # « *'test'* »

Remember that strings with different types of quotes can be abutted (here we have a single-quoted string immediately followed by a double-quoted string) as it's the shell that processes quoted strings before executing the command line:

touch 'Quotes "here" at'" 5 o'clock"    # « Quotes "here" at 5 o'clock »
#     '←-first-string-→'"←-second-→"

Your example:

touch \'test\'                         # « 'test' »
touch \*\'test\'\*                     # « *'test'* »

ls -1 --quoting-style=literal # List files one per line 'test' 'test'

ilkkachu
  • 138,973
Chris Davies
  • 116,213
  • 16
  • 160
  • 287
3

If I write touch \'test\'

ls shows 'test'

No! It shows "'test'".

But if I write touch \*\'test\'\*

ls now shows *'\''test'\''*

No! It shows '*'\''test'\''*'.

Modern versions of GNU ls show file names in a way that can be typed in Bourne-style shells (bash, zsh, etc., and I think it's also compatible with fish). You could have created these files with touch "'test'" and '*'\''test'\''*' (but of course there are several ways to do the quoting, and there's nothing wrong with choosing a different one).

You can tell ls to use a different way to show special characters, for example ls --literal to print whatever the file name is (even if the result is ambiguous, for example if the name contains spaces that can be confused with a column display, or if the name contains newlines or unprintable characters). See the documentation of --quoting-style for other available styles.

2

On some systems, ls adds single quotes to file-names with "special" characters. See this question for details.

Since you want single quotes in the final file-name, you may use double quotes (as long as there are no other files in the directory). On my Ubuntu 22.04, this works as expected:

touch "*'test'*"
ls --quoting-style=literal
Hermann
  • 6,148