- Is space not allowed in a filename?
- 4 Answers 4
- OUTPUT
- How to reference filename with spaces in Linux
- How to access files/directories in the terminal with spaces in the name:
- How to create a file and directory with space in its name:
- How to read a file with space in its name:
- How to access files/directories with spaces in the name? [duplicate]
- 2 Answers 2
Is space not allowed in a filename?
How do you use or deal with a space in a filename correctly?
You can do it, it’s allowed, like creating a self-destruct script called «cd» but you shouldn’t do it. Your file already looks different in 3 different tools, isn’t that bad enough?
Not everyone shares the opinion that it’s really, really annoying. And «There is no reason for it» is so obviously false that it doesn’t need refuting. I gave in and learned how to handle spaces properly years ago, and for the most part it’s really not a big deal.
@snailboat Spaces are a symptom of the real problem which is a lack of standardization. Unix filesystems allow file «names» to nearly unrestricted binary blobs. The only illegal bytes are 0 and 47 (the / separator). Using all 254 remaining bytes opens the door to all manners of unspeakable eldritch «names». Obviously this is insane, but not everyone agrees on what «sane» is, and different characters will break different tools. The intersection of everyone’s sanity is quite small.
4 Answers 4
Spaces, and indeed every character except / and NUL, are allowed in filenames. The recommendation to not use spaces in filenames comes from the danger that they might be misinterpreted by software that poorly supports them. Arguably, such software is buggy. But also arguably, programming languages like shell scripting make it all too easy to write software that breaks when presented with filenames with spaces in them, and these bugs tend to slip through because shell scripts are not often tested by their developers using filenames with spaces in them.
Spaces replaced with %20 is not often seen in filenames. That’s mostly used for (web) URLs. Though it’s true that %-encoding from URLs sometimes makes its way into filenames, often by accident.
It’s «URL encoding» or «percent encoding» en.wikipedia.org/wiki/URL_encoding As per that the most appropriate name is probably «URI encoding», but people find url easier to say than U.R.I., so this is a common form of misnomer. Notice the set of reserved characters in URI’s is larger than it is for *nix filenames.
@Tim I don’t know that you can specify a NUL character in any command line argument in bash . I tried a few things such as quoting it with Ctrl-V and something like $(echo -e \\0) but it didn’t work. The thing is, the reason NUL can’t be used in filenames is that it can’t be used in C strings (because it’s the string terminator) and all the underlying APIs as well as virtually all strings handled by C programs use that format. Since bash is written in C, it might simply have no support at all for any strings with NUL in them. I could be wrong, there might be some obscure way.
Sort of depends on the context. String functions generally don’t count the final null (or rather, the first null is the end of the string, even if there’s stuff after it), so in that sense it has zero length and therefore would be considered empty.
@Celada of course you can use NUL and bash, you need $’\0′ . For example: find . -print0 | while read -d $’\0′ f; do echo «$f»; done
Spaces are allowed in filenames, as you have observed.
If you look at the «most UNIX filesystems» entry in this chart in wikipedia, you’ll notice:
- Any 8-bit character set is allowed. We can subsume 7-bit ASCII under this umbrella too, since it is a subset of various 8-bit sets and is always implemented using 8 bit bytes.
- The only forbidden characters are / and «null». «Null» refers to a zero byte, but these are not allowed in text data anyway.
However, if you make any use of the shell, you may realize that there are some characters that will create a hassle, most significantly * , which is a POSIX globbing operator.
Depending on how you want to define «hassle», you could include whitespace (spaces, tabs, newlines, etc.) in there, as this creates the need for quoting with «» . But this is inevitable, since spaces are allowed, so.
How do you use or deal with a space in a filename correctly?
In a shell/command line context, wrap the filename in single or double quotes (but note they are not the same WRT other issues), or escape the spaces with \ , e.g.:
> foo my\ file\ with\ spaces\ in\ the\ name
You can’t. The «execve semantics» refers to the fact that in C (and every other language I’m aware of), text strings are null terminated. The shell is implemented in C. The sneakest thing I could think of is touch $(echo -e «foo\00bar») — -e processes \0N as an octal value, but it still gets lost somewhere, as that just creates a file named foobar . Of course NULL isn’t printable, but I guarantee it’s gone from there because of the C string restriction.
«text strings are null terminated» -> To explain further: strings are always stored with a zero byte at the end, which is why it «isn’t allowed» in text: If you insert one, you’ve effectively terminated the string at that point. Eg., foo[NULL]bar would end up as foo for most intents and purposes. The fact that doesn’t happen with that echo -e shows the NULL has been pruned out somewhere.
A vast majority of programming languages do allow null characters in strings. It just happens that the main language that doesn’t is C, which Unix is built on — and most Unix shells don’t allow null characters in strings either. In any case, @Tim, all Unix interfaces use null-terminated strings, so a null byte is the one thing you cannot ever have in a file name (plus / which is the directory separator and cannot be quoted, so can be in a pathname but not in a filename).
. but [never mind again]. Not something I would do too often, anyway. To my mind there’s no reason for them to be in textual data. I would have corrected that, but it’s a comment.
The reason is largely historical — WAY back in the mists of time spaces were not allowed in filenames, so spaces were used as keyword / filename separators. Future shell interpreters had to be reverse-compatible with old scripts, and thus we are stuck with the headache we have today.
Developers of processes that do not need to deal with humans very much can make things much, much easier by dropping spaces altogether. Apple does this, the contents of /System/Library/CoreServices/ contains very few spaces, the programs with spaces are opened on behalf of the user, andWouldLookStrangeIfCamelCased. Similar unix-only paths also avoid spaces.
( somewhat related anecdote: in the mid-90’s a Windows drone said «Name one thing you can do on a Mac that I can’t do on Windows» -> «Use 12 characters in a filename.» -> Silence. Spaces were also possible in those 12 characters)
I used to use V6 Unix (c. 1978). Spaces were allowed then. One task I had was to write a program to parse the file system (using direct disk i/o) and look for a file which had spaces and backspaces in its name.
So yes, as is stated many times elsewhere, a filename can contain nearly any character. But it needs to be said that a filename is not a file. It does carry some weight as a file attribute in that you typically need a filename to open a file, but a file’s name only points to the actual file. It is a link, stored in the directory that has recorded it, alongside the inode number — which is a much closer approximation to an actual file.
So, you know, call it whatever you want. The kernel doesn’t care — all file references it will handle will deal with real inode numbers anyway. The filename is a thing for human consumption — if you wanna make it a crazy thing, well, it’s your filesystem. Here, I’ll do some crazy stuff:
First I’ll create 20 files, and name them with nothing but spaces, each filename containing one more space than the last:
until [ $((i=$i+1)) -gt 20 ] do v=$v' ' && touch ./"$v" done
This is kinda funny. Look at my ls :
Now I’m going to mirror this directory:
set -- * ; mkdir ../mirror ls -i1qdU -- "$@" | sh -c 'while read inum na do ln -T "$1" ../mirror/$inum shift ; done' -- "$@" ls -d ../mirror/*
Here are ../mirror/ ‘s contents:
../mirror/423759 ../mirror/423764 ../mirror/423769 ../mirror/423774 ../mirror/423760 ../mirror/423765 ../mirror/423770 ../mirror/423775 ../mirror/423761 ../mirror/423766 ../mirror/423771 ../mirror/423776 ../mirror/423762 ../mirror/423767 ../mirror/423772 ../mirror/423777 ../mirror/423763 ../mirror/423768 ../mirror/423773 ../mirror/423778
Ok, but maybe you’re asking — but what good is that? How can you tell which is which? How can you even be sure you linked the right inode number to the right filename?
echo "heyhey" >>./' ' tgt=$(ls -id ./' ') cat ../mirror/$ \ $(ls -1td ../mirror/* | head -n1)
OUTPUT
See, both the inode number contained in ../mirror/»$» and that referenced by ./’ ‘ refer to the same file. They describe the same file. They name it, but nothing more. There is no mystery, really, just some inconvenience you might make for yourself, but which will ultimately have little to no effect on the operation of your unix filesystem in the end.
How to reference filename with spaces in Linux
For Linux, the user terminal is the most crucial program to manage almost everything in the operating system. But many people do not prefer the command line because they assume that it is a very technical program and require particular expertise to use it. Though knowing it is pretty handy.
Various reasons keep a new Linux user away from the command line, one of them handling files in the terminal. Files and directories in Linux can have different names, and some names can have “spaces” in them. So what’s the big deal? The issue is, the terminal reads the “space” differently; for instance, if your directory has the name “new folder,” the terminal will assume two different directories, i.e., “new” and “folder.” Accessing such files in the terminal can become really frustrating. Luckily, there are various methods to deal with the files/folders with spaces in their names.
This guide is focusing on how to reference filename with spaces in Linux with different approaches. So let’s begin:
How to access files/directories in the terminal with spaces in the name:
In this section, we will be creating a file first with a “space” in its name; then, we will learn what errors we face while referring to it and then how to access it correctly in the terminal:
How to create a file and directory with space in its name:
Creating a file in Linux with “space” in its name is straightforward, open terminal, and run the command mentioned below:
The file can either be created by using apostrophes or quotation marks. The procedure of creating a directory is quite similar:
You can verify it by using the “ls” command in the terminal.
How to read a file with space in its name:
Before we learn the correct way to read a file with “space” in its name, let’s identify the error it can give. So when you try to read the above-created file (my file), you will get an error:
Now, let’s see what happens when you try to write something to the file:
As it can be seen that the above command, instead of writing the “my file,” creating a new file by the name of “my” and saving text to it. So, how to access such a file? Well, there are two approaches:
So first of all, let’s insert some text into the above-created file using ;“\”:
How to access files/directories with spaces in the name? [duplicate]
Through terminal I can’t access files or directories with a spaces in their names. The cd command says no such file or directory . Is there any way to do it or should I rename all files with spaces?
2 Answers 2
To access a directory having space in between the name use \ to access it. You can also use Tab button to auto completion of name.
guru@guru-Aspire-5738:~$ cd /media/Data/My\ Data/ guru@guru-Aspire-5738:/media/Data/My Data$.
To to use files with spaces you can either use the escape character or youse the double quotes.
\ is called escape character, used to not expansion of space, so now bash read the space as part of file name.
Now to rename files, it’s so easy to rename all files with spaces and replace space with underscore:
for file in * ; do mv "$f" "$" ; done
look at answer here there is a script to rename all files and dirs recursively.
The script is:(All rights go to its owner)
#!/bin/bash # set -o xtrace # uncomment for debugging declare weirdchars=" &\'" function normalise_and_rename() < declare -a list=("$") for fileordir in "$"; do newname="$]/_>" [[ ! -a "$newname" ]] && \ mv "$fileordir" "$newname" || \ echo "Skipping existing file, $newname." done > declare -a dirs files while IFS= read -r -d '' dir; do dirs+=("$dir") done < <(find -type d -print0 | sort -z) normalise_and_rename dirs[@] while IFS= read -r -d '' file; do files+=("$file") done < <(find -type f -print0 | sort -z) normalise_and_rename files[@]