60

I managed to make a directory literally named ~.

(Apparently, Python's os.mkdir('~/something') does this.)

How do I remove it without nuking my home?

Also, if it helps, I have my real /home on a separate partition. And the duplicate ~ is located in (the real ) ~.

4
  • 52
    Obligatory XKCD. Ok, I may have lied about it being obligatory. And being an XKCD. Apr 7, 2016 at 18:41
  • 30
    To answer the Python question you didn't ask, in future, use os.mkdir(os.path.expanduser('~/something')). Apr 8, 2016 at 2:22
  • 8
    ... just for curiosity, since you created the directory in python didn't you think to do os.rmdir('~/something') to delete it?
    – Bakuriu
    Apr 9, 2016 at 9:01
  • @Bakuriu Eventually, I did figure that out
    – user423626
    Apr 9, 2016 at 10:08

5 Answers 5

78

Escape the ~ with \~ or use single quotes '~'. so you can

rmdir ~/\~

or

cd ~ ; rmdir '~'
5
  • 49
    If you are worried about deleting something you shouldn't, you could first do something non-destructive like: mv '~' normalname, then remove the directory normalname. Apr 7, 2016 at 20:41
  • 55
    rmdir is non-destructive. rmdir will only delete directories that are empty, so if you try to rmdir any directory that has anything at all in it, rmdir will refuse to delete it. Apr 8, 2016 at 0:09
  • 3
    You don't even need to escape the tilde in the first of these commands -- ~ is expanded specially only at the beginning of a shell "word". Apr 9, 2016 at 21:27
  • 1
    You can even just rmdir *. As it only removes empty directories, you don't need to worry about it doing anything destructive.
    – Benubird
    Apr 10, 2016 at 13:19
  • @ChrisJefferson: If you want to check your command first, use ls -d to see if it lists the directory or file you want it to. No need for anything with an effect like mv. Apr 10, 2016 at 16:10
43

What python giveth, python taketh away:

$ python -c 'import os; os.makedirs("~/foo")'; tree; python -c 'import os; os.removedirs("~/foo")'; tree
.
└── ~
    └── foo

2 directories, 0 files
.

0 directories, 0 files

If you did os.mkdir, you could undo it with os.rmdir (and similarly for os.makedirs and os.removedirs).

36

You can either escape the directory name using a backslash like this (assuming you're operating in the parent directory of the one you want to delete):

rmdir \~

Or you can use relative paths with a dot as the current directory (also when located in the parent directory):

rmdir ./~

Or you can use the full absolute path:

rmdir /home/USERNAME/~

And no worries, rmdir can only remove empty directories. If you accidentally mistype the command and the path would evaluate to your real home directory, it is not in danger because it contains files:

$ rmdir directory_with_files
rmdir: failed to remove ‘directory_with_files’: Directory not empty
1
  • I like the relative path option. It should be impossible to map ./~ to ~/, regardless of which directory you're currently in. Similar situation with the full absolute path.
    – MBraedley
    Apr 11, 2016 at 17:22
3

find command can do such miracles. The command

ls -i

will give you inode number of files or directory. Then you can use find to delete such files or directory using:

find . -inum <inode-number> -delete #for a file

and

find . -inum <inode-number> -exec rm -rf {}\; #for directories
1

What should have been done

You should have performed home=os.path.expanduser("~") first and then os.path.join(home,"something"). The ~ is treated as text in python and doesn't expand like it does in bash or other shells.

$ python -c 'import os;home=os.path.expanduser("~"); os.mkdir(os.path.join(home,"something"))'                                                                                          

$ ls -ld ~/something
drwxrwxr-x 2 xieerqi xieerqi 4096 7月  12 21:00 /home/xieerqi/something/

How to get rid of it

In addition to the already mentioned methods, we can use hex value for ~ from the ascii table of characters, which unlike actual ~ doesn't expand to user's home directory on command line (In case you're wondering, when tilde appears at the beginning of a word, it expands to user's home directory. Compare ls ~ and ls $'\x7e').

Here's how it would work:

# Make the directory
$ mkdir ./~                                                                                                                                                                             
$ stat ./$'\x7e'                                                                                                                                                                        
  File: './~'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: 801h/2049d  Inode: 5768019     Links: 2
Access: (0775/drwxrwxr-x)  Uid: ( 1000/ xieerqi)   Gid: ( 1000/ xieerqi)
Access: 2017-07-12 21:05:31.382828424 -0600
Modify: 2017-07-12 21:05:31.382828424 -0600
Change: 2017-07-12 21:05:31.382828424 -0600
 Birth: -

# and remove it 
$ rmdir ./$'\x7e'                                                                                                                                                                       
$ ls $'\x7e'
ls: cannot access '~': No such file or directory
1
  • Shouldn't '~' suffice?
    – CherryDT
    Sep 25, 2021 at 18:33

You must log in to answer this question.