Some more information:

I was backing up a large directory with tar, only there were a couple of large files there that I didn't expect. This connection is over the network and very slow, so simply waiting it out is not an option.

None of these files have anything important in them.

I erased the content of the first few with the echo > file, which preserved the link so tar would stop reading them, but then I and rm -rf'd an entire directory while tar was reading a 2GB file in that directory. Now, tar holds the only link to it, and I can't seem to find any way of making it move on it short of starting over completely.

The file is on an ext4 filesystem being accessed over the network by sshfs.

  • 1
    (NAA since I have no box here to check the details, but I think you can access that file through /proc/(pid of tar)/fd/(number) or somesuch, and maybe you can truncate it with echo as you did with the others.) – Ulrich Schwarz Sep 30 '15 at 21:46
  • You could probably trace tar with gdb or similar and force it to think it found EOF on that file... (Not posting as an answer because this requires a lot of explaining and some testing—anyone else who wants to is welcome to steal the idea for his/her answer.) – derobert Sep 30 '15 at 21:48
  • 1
    You could run gdb, attach to the tar process, get it to stop during a read() from the file, then give gdb the return (int)-1 command to make tar think the read failed. – Mark Plotnick Sep 30 '15 at 21:49
  • @Mark I think gdb has a way to break on functions.. This sounds like it could work. – Functino Sep 30 '15 at 21:51
  • I think it also provides a way to override the return value, so you could return 0, signaling EOF. – Functino Sep 30 '15 at 21:58

echo >file would have been the straightforward solution. But once you've deleted the file, that's no longer possible.

But wait! Since you're using an ext4 filesystem, I presume that this tar is running on Linux. (Some but not all other Unix variants allow a similar solution.) On Linux, you can still access a deleted-but-open file via /proc/PID/fd/FD where PID is the process ID of the process that has the file open and FD is the file descriptor through which the file is open. This file is a symbolic link to the file, but it's a magic one. It remains valid even if the file is deleted. If you look at it with ls -l, you'll see something like

/proc/1234/fd/4 -> /path/to/file (deleted)

in all appearance a broken link, but you actually can open this file. In particular, you can truncate it with something like : >/proc/1234/fd/4.

If you're working on a system without /proc, you can use a debugger to cause the tar process itself to perform the truncation for you. Attach the debugger to the process, then make it execute truncate(4) where 4 is the file descriptor that tar is reading from. For example, with GDB, you can try something like

$ ps
…     find the PID of the tar process, e.g. 1234
$ lsof -p1234
…     find the file descriptor that you want to act on, e.g. 4
$ gdb -pid 1234
(gdb) call truncate(4)
(gdb) detach

This may or may not confuse tar as it could render some data structure that it's using inconsistent, so I recommend experimenting before trying it out for real.


Stop the tar?

ps aux | grep tar

Find the pid of the tar process

kill $PID
  • Unfortunately, this means starting over a procedure that's already taken a long time. I'll probably wait another hour and if there really is no way to simply tell tar to "forget about this one," I'll bite the bullet. – Functino Sep 30 '15 at 21:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.