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 ) ~.

Seth
  • 58,122

5 Answers5

78

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

rmdir ~/\~

or

cd ~ ; rmdir '~'
muru
  • 197,895
  • 55
  • 485
  • 740
  • 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. – Chris Jefferson Apr 07 '16 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. – Hitechcomputergeek Apr 08 '16 at 00: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". – hmakholm left over Monica Apr 09 '16 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 '16 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. – Peter Cordes Apr 10 '16 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).

muru
  • 197,895
  • 55
  • 485
  • 740
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
Byte Commander
  • 107,489
  • 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 '16 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
gjois
  • 131
  • 3
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
Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497