Due to an application bug as yet undiagnosed, I have several hundred servers with a full disk. There is one file that has been filled up with duplicate lines—not a log file, but a user environment file with variable definitions (so I can't just delete the file).
I wrote a simple sed
command to check for the erroneously added lines and delete them, and tested it on a local copy of the file. It worked as intended.
However, when I tried it on the server with the full disk, I got approximately the following error (it's from memory, not copy and paste):
sed: couldn't flush /path/to/file/sed8923ABC: No space left on deviceServerHostname
Of course, I know there's no space left. That's why I'm trying to delete stuff! (The sed
command I'm using will reduce a 4000+ line file to about 90 lines.)
My sed
command is just sed -i '/myregex/d' /path/to/file/filename
Is there a way I can apply this command despite the full disk?
(It must be automated, since I need to apply it to several hundred servers as a quick-fix.)
(Obviously the application bug needs to be diagnosed, but in the meantime the servers aren't working correctly….)
Update: The situation I faced was resolved by deleting something else that I found out I could delete, but I'd still like the answer to this question, which would be helpful in the future and for other people.
/tmp
is a no-go; it's on the same filesystem.
Before I freed up disk space, I did test and find out that I could delete the lines in vi
by opening the file and running :g/myregex/d
and then successfully save the changes with :wq
. It seems it should be possible to automate this, without resorting to a separate filesystem to hold a temp file…. (?)
Best Answer
The
-i
option doesn't really overwrite the original file. It creates a new file with the output, then renames it to the original filename. Since you don't have room on the filesystem for this new file, it fails.You'll need to do that yourself in your script, but create the new file on a different filesystem.
Also, if you're just deleting lines that match a regexp, you can use
grep
instead ofsed
.In general, it's rarely possible for programs to use the same file as input and output -- as soon as it starts writing to the file, the part of the program that's reading from the file will no longer see the original contents. So it either has to copy the original file somewhere first, or write to a new file and rename it when it's done.
If you don't want to use a temporary file, you could try caching the file contents in memory: