Can't redirect grepped output of free memory utility to a file

Viewed 77

I can't seem to redirect the grepped output of the free memory utility to a file. The file is empty. The command does produce screen output. Moreover, upon removing the piped grep, it works! Below is the session:

$ free -s 5 -m|grep Mem #Produces screen output
Mem:           7745         279        5645           0        1820        7185
Mem:           7745         279        5645           0        1820        7185
^C
$ free -s 5 -m|grep Mem >& mem.log
^C
$ cat mem.log #File is empty
$ ls -l mem.log #Confirming file is empty
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 10 23:59 mem.log
$ free -s 5 -m >& mem.log #Removing the grep and retrying
^C
$ cat mem.log #Now file contains the data
              total        used        free      shared  buff/cache   available
Mem:           7745         278        5645           0        1821        7186
Swap:             0           0           0

Any idea what is going on? Is this a bug?

1 Answers

Like most C programs, grep's output is line-buffered if it's writing to a terminal, but fully buffered if stdout is redirected to a file or pipe. Fully buffered means it has an internal buffer, usually 4KB, and only prints something when that buffer fills up.

You can work around it by using grep --line-buffered to force it to use line buffering. This option tells it to print out its matches immediately. This isn't the default behavior because it's slower than full buffering.

A better option is to just run free -m instead of free -s 5 -m so that free prints the free memory and exits. When you use -s 5 it runs forever, which in turn causes grep to run forever and never flush its output, and is why you have to Ctrl-C it each time. Remove -s 5 and grep will Just Work.

Related