truncate deleted files from lsof

lsof|gawk '$4~/txt/{next};/REG.*\(deleted\)$/{printf ">/proc/%s/fd/%d\n", $2,$4}'
While the posted solution works, I'm a bit uneasy about the "%d" part. This would be hyper-correct approach: lsof|gawk '$4~/txt/{next};/REG.*\(deleted\)$/{sub(/.$/,"",$4);printf ">/proc/%s/fd/%s\n", $2,$4}' Oh, and you gotta pipe the result to sh if you want it to actually trim the files. ;) Btw, this approach also removes false negatives (OP's command skips any deleted files with "txt" in their name).

By: wejn
2014-03-11 10:40:32

1 Alternatives + Submit Alt

What Others Think

Now there are two versions of this command, but neither of you have explained WHY you'd do this. Deleted doesn't necessarily mean not-in-use. Lots of programs create then immediately delete temporary files, but keep a handle to them (to continue working). That means when the program closes, the files automatically disappear.
flatcap · 393 weeks and 6 days ago
@flatcap I figured jim80net had a reason for writing a thing like this. I merely took it as an exercise to make the one-liner more effective (and hopefully free of false negatives). As for the reason why you might want to do that... well, suppose you have a network server written in a garbage collected language (i.e. Java). The said server has a strong ref that prevents it from releasing a (now useless) fd. Perhaps a reference leak of some kind. So even if you delete the file it still doesn't free the resources allocated by that file (since there's open fd in the system). Truncating the file via /proc/$pid/fd/$fdno frees the allocated blocks... and allows you to keep the abovementioned server running (if you don't mind a stray open fd). Now, in my 15+ year career I've only used something akin to this a handful of times... but it sometimes happens that you really need to free allocated blocks from already deleted file without killing some kind of a service. It's not an everyday task... but i'd say that if you play long enough with UN*Xes, you're bound to stumble upon a situation that calls for this.
wejn · 393 weeks and 6 days ago
@wejn: Thanks for the reply. It's the sort of command that shouldn't be necessary... :-)
flatcap · 393 weeks and 6 days ago
My only comment is '{printf ">/proc/%s/fd/%d\n", $2,$4}' should be '{printf ":>/proc/%s/fd/%d\n", $2,$4}' I agree with flatcap as well, it's usually only called for from misbehaving or misconfigured programs. Next time I need it though, I'll use wejn's version, as I'm impressed by the gawk foo! =]
jim80net · 393 weeks and 6 days ago
@jim80net for bash ">file" works the same as ":>file". And I'm actually not fond of the latter, because ":" could be aliased or defined as some function. Reminds me of the notorious: :(){ :|:& };: fork bomb I'm wearing on my t-shirt. ;) If I had to stick something before the ">" character I'd probably go with /bin/true. ;) YMMV, though.
wejn · 393 weeks and 5 days ago

What do you think?

Any thoughts on this command? Does it work on your machine? Can you do the same thing with only 14 characters?

You must be signed in to comment.

What's this? is the place to record those command-line gems that you return to again and again. That way others can gain from your CLI wisdom and you from theirs too. All commands can be commented on, discussed and voted up or down.

Share Your Commands

Stay in the loop…

Follow the Tweets.

Every new command is wrapped in a tweet and posted to Twitter. Following the stream is a great way of staying abreast of the latest commands. For the more discerning, there are Twitter accounts for commands that get a minimum of 3 and 10 votes - that way only the great commands get tweeted.


Subscribe to the feeds.

Use your favourite RSS aggregator to stay in touch with the latest commands. There are feeds mirroring the 3 Twitter streams as well as for virtually every other subset (users, tags, functions,…):

Subscribe to the feed for: