Перенаправление из файла через конвейер обратно в тот же файл небезопасно; если file.txt
перезаписывается оболочкой при настройке последней ступени конвейера до того, как tail
начнет считывать первую ступень, вы получите пустой вывод.
Вместо этого выполните следующие действия:
tail -1 file.txt >file.txt.new && mv file.txt.new file.txt
... ну, на самом деле, не делайте этого в рабочем коде; особенно если вы находитесь в среде, чувствительной к безопасности, и работаете от имени пользователя root, более уместно следующее:
tempfile="$(mktemp file.txt.XXXXXX)"
chown --reference=file.txt -- "$tempfile"
chmod --reference=file.txt -- "$tempfile"
tail -1 file.txt >"$tempfile" && mv -- "$tempfile" file.txt
Другой подход (исключение временных файлов, если <<<
неявно создает их на вашей платформе) заключается в следующем:
lastline="$(tail -1 file.txt)"; cat >file.txt <<<"$lastline"
(Вышеприведенная реализация зависит от bash, но работает в тех случаях, когда echo нет - например, когда последняя строка содержит «--version»).
Наконец, можно использовать губку из moreutils :
tail -1 file.txt | sponge file.txt