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
/home/pi/Documents/testand 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
$()is called command substitution which executes
tail -n 50 /home/pi/Documents/test
- the quotation marks preserve line breaks in the output.
> /home/pi/Documents/testredirects output of
echo "$(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.