Ever mistakenly pipe output to a file with special characters that you couldn’t remove?
-rw-r–r– 1 eriks eriks 4 2011-02-10 22:37 –fooface
Good luck. Anytime you pass any sort of command to this file, it’s going to interpret it as a flag. You can’t fool rm, echo, sed, or anything else into actually deeming this a file at this point. You do, however, have a inode for every file.
Traditional methods fail:
[eriks@jaded: ~]$ rm -f –fooface
rm: unrecognized option ‘–fooface’
Tryrm ./--fooface' to remove the file
–fooface’.
Tryrm --help' for more information.
rm ./–fooface’ to remove the file
[eriks@jaded: ~]$ rm -f '--fooface'
rm: unrecognized option '--fooface'
Try--fooface'.
rm –help’ for more information.
Try
So now what, do you live forever with this annoyance of a file sitting inside your filesystem, never to be removed or touched again? Nah.
We can remove a file, simply by an inode number, but first we must find out the file inode number:
$ ls -il | grep foo
Output:
[eriks@jaded: ~]$ ls -il | grep foo
508160 drwxr-xr-x 3 eriks eriks 4096 2010-10-27 18:13 foo3
500724 -rw-r–r– 1 eriks eriks 4 2011-02-10 22:37 –fooface
589907 drwxr-xr-x 2 eriks eriks 4096 2010-11-22 18:52 tempfoo
589905 drwxr-xr-x 2 eriks eriks 4096 2010-11-22 18:48 tmpfoo
The number you see prior to the file permission set is actually the inode # of the file itself.
Hint: 500724 is inode number we want removed.
Now use find command to delete file by inode:
# find . -inum 500724 -exec rm -i {} \;
There she is.
[eriks@jaded: ~]$ find . -inum 500724 -exec rm -i {} \;
rm: remove regular file `./–fooface’? y
And done.
Tweet
WOW KIREGUY, YOU’RE AWESOME. THANKS KIREGUY.
Seems rather unnecessary in this example, sir. rm ./-fooface will work
BUT GOOD JOB ANYWAYS AIRICK
THANKS!!!
GREETINGS FROM BRAZIL!!
The correct way to prevent interpreting option arguments is: `rm — -fooface’.
To get filenames with unprintable characters and other such braindamage in shell-escaped format, in Bash, ksh93, or Zsh, use:
printf ‘%q\n’ ./*
and just pass the relevant string or expansion. e.g.
rm — $’./\31204′
Alternatively, if you don’t want to mess with -exec, you can pass -delete instead. You should also pass -depth 1.
“unlink –fooface” would work as well, as unlink doesn’t accept any flags.