How keep last 50 lines in logfile
The problem is that your shell is setting up the command pipeline before running the commands. It's not a matter of "input and output", it's that the file's content is already gone before tail even runs. It goes something like:
- The shell opens the
>
output file for writing, truncating it - The shell sets up to have file-descriptor 1 (for stdout) be used for that output
- The shell executes
tail
. tail
runs, opens/home/pi/Documents/test
and finds nothing there
There are various solutions, but the key is to understand the problem, what's actually going wrong and why.
This will produce what you are looking for,
echo "$(tail -n 50 /home/pi/Documents/test)" > /home/pi/Documents/test
Explanation :
$()
is called command substitution which executestail -n 50 /home/pi/Documents/test
- the quotation marks preserve line breaks in the output.
> /home/pi/Documents/test
redirects output ofecho "$(tail -n 50 /home/pi/Documents/test)"
to the same file.
Another solution to the file redirection clearing the file first is to use sponge
from the moreutils
packge like so:
tail -n 50 /home/pi/Documents/test | sponge /home/pi/Documents/test
This is because bash processes the redirection with the >
first, deleting the contents of the file. Then it executes the command. Were you to use >>
, the last 50 lines would be appended to the end of what's currently in the file. In this case, you'd have the same 50 lines repeated twice.
The command works as expected when redirecting to a different file. Here is one way to write the last 50 lines of a file to a file of the same name:
tail -50 /home/pi/Documents/test > /home/pi/Documents/test2 && mv /home/pi/Documents/test2 /home/pi/Documents/test
This first writes the last 50 lines to a temporary file, which is then moved using mv
to replace the original file.
As noted in the comments, this won't work if the file is still open. Moving the file also creates a new inode and may change ownership and permissions. A better way to do this using a temporary file would be:
tail -50 /home/pi/Documents/test > /home/pi/Documents/test2 ; cat /home/pi/Documents/test2 > /home/pi/Documents/test
The temporary file can also be removed, though each time this happens its contents will be overwritten.