Unix filenames are just sequences of bytes, and can contain any byte except /
and NUL
in any position. There is no built-in concept of an "extension" as there is in Windows and its filesystems, and so no reason not to allow filenames to end (or start) with any character that can appear in them generally — a .
is no more special than an x
.
Why does Unix allow files with a period at the end of the name? "A sequence of bytes" is a simple and non-exclusionary definition of a name when there's no motivating reason to count something out, which there wasn't. Making and applying a rule to exclude something specifically is more work.
Is there a use for it? If you want to make a file with that name, sure. Is there a use for a filename ending with x
? I can't say I would generally make a filename with a .
at the end, but both .
and x
are explicitly part of the portable filename character set that is required to be universally supported, and neither is special in any way, so if I had a use for it (maybe for a mechanically-generated encoding) then I could, and I could rely on it working.
As well, the special filenames .
(dot) and ..
(dot-dot), which refer to the current and parent directories, are mandated by POSIX, and both end with a .
. Any code dealing with filenames in general needs to address those anyway.
You're using some system where ls
outputs filenames with the shell's quoting rules, to make the output unambiguous. Possibly e.g. GNU ls with QUOTING_STYLE
set to shell
, or ls
from coreutils >= 8.25 where that is the default. The quoting rules of the shell are also important when entering the filenames on the command line.
gvim 'Chapitre 2 : L''accès au système.md'
created the file 'Chapitre 2 : Laccès au système.md'
instead, with no apostrophe at all.
You gave the shell two back-to-back single-quoted strings, which just get concatenated. In SQL, you can get a literal single quote that way, but in the most common shells you can't(†). The outer single quotes you show shouldn't be part of the file name, they're just what ls
shows to make the output unambiguous. The actual filename is Chapitre 2 : Laccès au système.md
.
(† POSIX-style shells (like Bash, ksh, and zsh with default settings), (t)csh, and fish take that as concatenation, which is how it works in e.g. Python too. Some other shells (rc/es/akanga) do what SQL does, though, and zsh has the rcquotes
option for that.)
gvim "Chapitre 2 : L'accès au système.md"
created a file named : "Chapitre 2 : L'accès au système.md"
It most likely created a file called Chapitre 2 : L'accès au système.md
. The double quotes aren't part of the name, they're just printed by ls
to make the output unambiguous. It used double quotes instead of single quotes here, since the name had a single quote but nothing that would be special in double quotes, so that format was the cleanest. Though
- Is (for the system) the file name :
"Chapitre 2 : L'accès au système.md"
the same than a file named 'Chapitre 2 : L'accès au système.md'
if I had succeded in doing so?
If those were the full filenames -- and they're valid as filenames! -- then no, they're not equivalent, since the other contains two double quotes and one single quote, and the other contains three single quotes.
If you mean if they're the same when interpreted using the quoting rules of the shell, then no, again. "Chapitre 2 : L'accès au système.md"
represents the string Chapitre 2 : L'accès au système.md
, as a single shell word (since the quotes keep it together).
On the other hand, 'Chapitre 2 : L'accès au système.md'
represents the strings Chapitre 2 : Laccès
, au
, système.md
(three distinct shell words since there are unquoted spaces) and an open quote with no closing partner. If you entered that on the shell command line, it would wait for input from another line in hope of getting the closing quote. If you entered those as arguments to a command on the shell command line without the final stray quote, that command would probably try to access those three distinct files.
- how should I write the file name in my gvim command to get the exact file name
'Chapitre 2 : L'accès au système.md'
I would like to read in the outpout of a ls command ?
You can't get ls
to output 'Chapitre 2 : L'accès au système.md'
in the mode where it outputs shell-style quoted strings, since that's not a valid shell-style quoted string: it has an unclosed quote in the end.
Now, if we go back to what you said first:
I had to edit a file whose name had to be : Chapitre 2 : L'accès au système.md
, with an apostrophe inside of it.
There's a few ways to represent that in the shell. One of them is using double quotes, which ls
also did for you: "Chapitre 2 : L'accès au système.md"
. This works because none of the characters inside are special in double quotes (it only has spaces and the single quote to protect), but wouldn't work if the filename contained e.g. a dollar sign. If it did have dollar signs, you could escape them with a backslash: \$
.
Another way is to use single quotes for everything but the single quote itself, and to put an escaped single quote where we want one: 'Chapitre 2 : L'\''accès au système.md'
. That has three parts: 'Chapitre 2 : L'
, \'
, and 'accès au système.md'
, the quotes and backslash get removed, and the result is concatenated to the single word Chapitre 2 : L'accès au système.md
.
Best Answer
A filename may not be empty. To quote the Single Unix Specification, §3.170, a filename is:
So, it must consist of at least 1 byte, i.e., not empty.
Not that from that definition, none of those characters need to be visible (i.e., could all be whitespace) nor do they need to be printing (could all be control characters). And if you're assuming file names are UTF-8, they need not be.