Как бы вы ни решили эту проблему, вам придется буферизовать вывод команды до тех пор, пока вы не сможете прочитать последнюю строку, чтобы знать, куда ее записать.
Единственный разумный способ сделать это — использовать временный файл, а затем переименовать его:
tmpfile=$(mktemp)
outfile=$(command | tee "$tmpfile" | tail -n 1)
mv "$tmpfile" "$outfile"
Ты можешь измениться |
к |&
если вы действительно хотите захватить как stdout, так и stderr, но имейте в виду, что это май приводит к названию выходного файла после сообщения об ошибке (хотя, вероятно, есть способ избежать этого, используя умный файловый дескриптор fu).
Можно реализовать альтернативное решение, используя губка
команда (из пакета больше утилит
), но, вероятно, использует ту же технику под капотом. На самом деле, справочная страница говорит
Когда это возможно, губка создает или обновляет выходной файл атомарно,
переименование временного файла на место.
Другим вариантом может быть использование оборот
перевернуть строки так, чтобы вы могли сначала прочитать последнюю строку, а затем оборот
снова, чтобы восстановить порядок вывода. Однако это включает буферизацию всего вывода дважды.