The answer depends on what you mean by really gone and also depends upon
your file system, your OS, and rm itself.
It can also depend upon what removed the file: did you do it with "rm" or did some other
program or script do the removal? To understand what options you may or may not have, we
need to look at what "rm" does.
First: traditional Unix:
When you rm a file all that happens is that the directory entry
is set to point at 0 instead of the inode it did point at, and the
link count for the inode is decremented by one. If the link count
has reached 0, and no process has the file open, then the inode
itself is marked us unused, and the disk blocks that the file used
are returned to the free list. If a process has the file open then
the release of the inode and the reclaim of disk blocks waits until
the process is done.
So, at this point, your data is still there until some other
process needs disk blocks and these happen to get reused. If
nothing asks for new blocks, or these blocks get put at the end of
the free list, you might be able to recover the data by scrounging
through the free list.
Some systems mess with rm either by an alias or a binary to
store the "deleted" file somewhere safe for a while. These systems will provide some recovery method also, of course.
Many systems alias "rm" to run "rm -i". That can be very annoying, but you can easily avoid it by being explicit: /bin/rm file.
That alias doesn't help you with getting back deleted files, but it's common enough that I want to mention it here. On my systems, I remove that alias immediately.
Seriously: how often do you screw up and remove something
you shouldn't have? Sure, it happens: misplaced wildcards or
a slip of the finger can do it. More than once I've meant to
do something like "rm *.bak" and accidentally put a space after the "*".
This stuff happens, but it happens so infrequently that it's
not worth putting up with "rm -i" the rest of the time.
And when I do screw up, how bad can the damage be if I'm
not running as root?
If you do happen to be root, the damage can be horrible.
I have to admit that yes, I have (once) accidentally typed
"rm -r /". Worse, I did it during a training session on
a live system. The results were dramatic and embarrassing.
Fortunately I saved most of it by immediately pulling the power
plug, so little had a chance to commit from cache, but I still had
a bit of restoring to do. That was a bad day.
I think that while "rm -i" is annoying, a new "-ii" (intelligent interactive) could be less so. In my version, "rm -ii" would be silent and
immediately obedient when asked to remove one file. With more than
one, the first thing it would do is get an approximate count - to save
time it wouldn't look very far, but might instead say "You are matching
more than 20 files". Perhaps both of these limits should be user
configurable: "rm -ii 1:20" is clumsy. but as it would probably
ordinarily be used as an alias, that's unimportant. The most important
part is the simple addition of a "c" answer, which would stop
asking for confirmation and just remove the remaining files. You
could give that at any time, of course. That "ii" could save you
from disaster without being quite so annoying.
First thing is to look at the script or application documentation to see what it really does - that may give you important information about what it really did. Your data could be tucked away safely already.
If the the application still has the file open, its data blocks will not be
deleted until it closes the file. Therefore, using a tool like
"lsof" can find the inode number of the file. Armed with that, you
could use a filesystem debugger like debugfs (for ext2, see link earlier) to set the link
count for that file back to 1. Actually, if you know the name of the
file already, you can skip lsof and go right to the file system
debugger. Your only remaining problem would be to recreate a directory
entry for it, which again you can do with a good fsdb. I haven't used
debugfs (and of course that assumes an ext fs), but it looks like it has
the necessary commands for all that.
Let's illustrate this with a simple example. I'll use "less" to look at a file and in
another window I'll find out everything I need to know:
9:26 up 3:37, 6 users, load averages: 0.46 0.59 0.63
USER TTY FROM LOGIN@ IDLE WHAT
tony console - 5:50 3:36 -
tony s002 - 5:51 - w
tony s001 - 5:51 57 -bash
tony s000 - 5:51 - ssh firstname.lastname@example.org
tony s003 - 8:28 1 less foo.t
tony s004 - 9:20 5 -bash
I can see that "tony" is using "less" on "foo.t". Let's get more:
# ps -ts003
PID TTY TIME CMD
1320 ttys003 0:00.04 login -pf tony
1321 ttys003 0:00.03 -bash
1658 ttys003 0:00.00 less foo.t
# lsof -p 1658
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
less 1658 tony cwd DIR 1,2 5984 501763 /Users/tony/Downloads
less 1658 tony txt REG 1,2 137712 36113911 /usr/bin/more
less 1658 tony txt REG 1,2 600576 36113586 /usr/lib/dyld
less 1658 tony txt REG 1,2 302137344 60870019 /private/var/db/dyld/dyld_shared_cache_x86_64
less 1658 tony 0u CHR 16,3 0t33139 711 /dev/ttys003
less 1658 tony 1u CHR 16,3 0t33139 711 /dev/ttys003
less 1658 tony 2u CHR 16,3 0t33139 711 /dev/ttys003
less 1658 tony 3r CHR 2,0 0t0 304 /dev/tty
less 1658 tony 4r REG 1,2 1719027 62534493 /Users/tony/Downloads/foo.t
So, the full file name is /Users/tony/Downloads/foo.t and its inode is 1719027. If it
was not "less" but rather some application that had removed foo.t but still had it open, that's all
we'd need to go after the data blocks.
Realize that the blocks might be overwritten by new data. There aren't any guarantees here.
You could also just power crash the machine. Probably not goood advice
in general, but fsck should find an unreferenced file with a non-zero
link count and stick it in lost+found. I am NOT recommending this as a
good method, but I confess I have done exactly that in past years on
Unixes where I didn't have the tools I needed to do anything else.