24

I'm working in a UNIX environment and I noticed that inside my working directory, which is miles and miles away from my UNIX home, there is a ~.

Now, once in the past, I did rm -rf ~ from my working directory and ended up erasing my home directory completely and had to involve IT.

I do not want to do it again. At the same time, I want to know:

  1. Why is ~ created in my working directory? Is it a faulty finger slip while saving (:w! but what happens is :w~ ?!!)

  2. Before checking in, there is a script that looks for extra files or folders that p4 is not aware so this ~ might cause an issue. How can I remove the ~ from my working directory and at the same time not erase my home?

I do have a backup command called del that I use instead of rm -rf. It just places stuff in a temporary location. I could use that and get rid of the ~, but I'm more interested in knowing why this happens, and how I can remove it.

0

3 Answers 3

40

Either quote it:

rm -i '~'
rm -i "~"
rm -i \~

Or reference it by a path, instead of just a basename:

rm -i ./~
rm -i /path/to/~

Note that, despite being a funny-looking single character name, this is conceptually no different than if you had created a file named SOME$PATH by doing

touch 'SOME$PATH'

And tried to remove it by doing:

rm -i SOME$PATH

(Warning: the variable SOME$PATH is not quoted for the sake of the example here. Normally it would be enclosed in quotes 'SOME$PATH' )

In both cases, the shell is expanding the name you give, and you need to prevent that.

Also: Don't use rm -rf to remove a file! The entire purpose for rm -r is to tell rm it's OK to remove directories. If you don't want to accidentally remove entire directories while trying to remove files, don't habitually pass -r!

5
  • 12
    I just tested this. :w~ in vim did create a file called ~. rm ~ returned cannot remove /home/seth it is a directory. rm "~" did remove the file. Just to underline don't pass -rf automatically.
    – Seth
    Jun 25, 2014 at 22:27
  • 5
    +1 for recommending to omit violent options by default. This is akin to doing kill -9 by default, which I've seen.
    – Celada
    Jun 26, 2014 at 0:24
  • I see that the example rm -i $FOO intentionally does not quote the variable for the sake of the example, but still: showing a shell example involving rm and an unquoted variable as argument is VERY BAD, uh, sorry, independent of context. I'm sure that can even be prooven :) I'll add some note - but maybe you could change the example, a little? Jun 26, 2014 at 0:37
  • @VolkerSiegel, Point taken - I took part of your edit, but the footnote seemed a bit too heavy handed. I also switched to a variable name even less likely to cause problems - most people don't have a file named SOME/bin:/usr/bin anywhere on their filesystem. :)
    – godlygeek
    Jun 26, 2014 at 1:30
  • Yes, looks good! (I was almost going to answer: What? Heavy-handed? Did you ever experience a real quoting problem in your live? ;) Just somewhat desparate about the amount of wrong shell examples out there, in general... Hey, it's hard to understand even without wrong examples! ) Jun 26, 2014 at 1:37
1

The tilde when used alone in the context of ls ~ will list your home dir as ~ is a shortcut to your home dir. If you did ls ~brown then you will list the contents of brown's home dir.

VIM, unless told otherwise, will create a back-up copy of a changed file: myFile myFile~.

This behavior is good as it creates a back-up but if you don't want it, add to you .vimrc file: set no backup (which I just accessed with vi ~/.vimrc).

And of course as others said, if you have a file called ~ then simply escape the char as \~

me 217 % vi this      (saved as :w~)
me 218 % ls
this  ~
me 219 % cat \~
kfdkdfk
me 220 % \rm \~
me 221 % ls
this
0

This could be effected by mistypes. If your TERM=xterm config is anything like mine, then practically every function key on your keyboard will send escape sequences like...

infocmp -1 | grep -n \~ | tail -n3
138:    kich1=\E[2~,
141:    knp=\E[6~,
142:    kpp=\E[5~,

More than half of the output of infocmp -1 contains ~tilde escapes on my machine - and I'm at a loss to understand what most of them do. I do know that zsh at least actually eats the escaped portion of the string in most cases - and leaves only the ~tilde.

For example, typing echo then <space> then F6 and <return> prints...

/home/mikeserv

The actual escape sequence sent is...

kf6=\E[17~

Interestingly, there are other of these escape sequences which contain > characters.

infocmp -1 | grep \>
is2=\E[!p\E[?3;4l\E[4l\E>,
rmkx=\E[?1l\E>,
rs2=\E[!p\E[?3;4l\E[4l\E>,

Those are commonly used escapes - reset and initialization strings. It's not difficult to imagine that a dropped keyboard or button-smash of some kind when an interactive shell is awaiting input could result in randomly truncated ~ files occurring throughout your file-system. At least, it does occasionally crop up on mine.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .