FreeBSD: Directory called ^C (really!) - how to remove?

Solution 1:

^V (ctrl+v) works as a kind of escape sequence for the next key-press, inserting the associated value instead of taking whatever action that would normally be associated.

Making use of this, ^V^C (ctrl+v, ctrl+c) ought to work for entering your difficult filename in the terminal.

Solution 2:

You may also remove the file by inode:

$ ls -i1
290742 foo
293246 ^C
$ find . -inum 293246 -delete

Whatever you do, for God's sake, do not put -delete before -inum:

$ touch foo bar baz quux
$ find . -name '*u*' -delete
$ ls
bar baz foo
$ find . -delete -name 'b*'
find: `./baz': No such file or directory
find: `./bar': No such file or directory
$ ls

Congratulations, you just wiped out all your files. With find, argument order matters!

Solution 3:

Another option is to use rm -ri ./*; rm will ask you before deleting any file and directory, so you just need to reply y to the "bad" file, and n to all the others.

Actually, in your case you can even cut down the number of replies needed by doing rm -ri ./?, as your "bad" file is just one character long.

Solution 4:

One option is to look up the file name with something other than ls. If you know it was produced by a verbatim Ctrl+C, you can find the ASCII character produced using a table of control characters, or with a more friendly interface like the one provided by Python:

>>> import os
>>> os.listdir('.')
['\x03', ...]

Another option would be to look at a hex dump of the output of ls, using e.g. hexdump.

Then you can delete the file with (for example) this bash command:

rmdir "$(printf '\x03')"

(The double quotes are only needed if the character you're trying to print is in your IFS variable, such as \x20 or \x0A, but it's a good habit to quote command substitutions unless you know you want the shell to perform field splitting, etc.)

Solution 5:

Often in this kind of situations it is easy to come up with a wildcard pattern that matches the relevant file.

In your case, this would be simply ? (matching all file names with precisely one character).

Just check that it really matches what you want:

ls -ld ?

And then remove the directory:

rmdir ?

You can also combine this with tab completion. You can type

rmdir ?

and press tab, and e.g. in bash it will be replaced by

rmdir ^C/

and you can then hit enter and it does what you want.