Перезаписать файл, только если данные

8

Я пытаюсь перезаписать файл с выводом команды, но только если есть какой-либо вывод. То есть я обычно хочу

mycommand > myfile

но если это заменит myfileпустые данные, я хочу сохранить старую версию myfile. Я думал, что что-то с использованием ifneдолжно быть возможно, а-ля

mycommand | ifne (cat > myfile) 

но это не работает ...

Косвенный подход

mycommand | tee mytempfile | ifne mv mytempfile myfile

работает, но я считаю использование этого временного файла нелегальным.

В: Почему моя первая идея не работает? Можно ли заставить его работать? Или есть другое хорошее и, возможно, совершенно другое решение для моей первоначальной проблемы?

Хаген фон Айцен
источник
5
«Перенаправление в отдельный файл, проверка размера этого файла и, возможно, его переименование» кажется мне довольно простым. Почему бы не использовать временный файл?
Джефф Шаллер

Ответы:

18

Ваш первый подход работает, вам просто нужно дать команду ifne(см. man ifne):

NAME
       ifne - Run command if the standard input is not empty

SYNOPSIS
       ifne [-n] command

DESCRIPTION
       ifne  runs  the  following command if and only if the standard input is
       not empty.

Так что вам нужно дать ему команду на запуск. Ты почти там, teeбудешь работать

command | ifne tee myfile > /dev/null

Если ваша команда не выдает огромное количество данных, если она достаточно мала, чтобы поместиться в переменную, вы также можете сделать:

var=$(mycommand)
[[ -n $var ]] && printf '%s\n' "$var" > myfile
Тердон
источник
8

Пешеходное решение:

tmpfile=$(mktemp)

mycommand >"$tmpfile"
if [ -s "$tmpfile" ]; then
    cat "$tmpfile" >myfile
fi

rm -f "$tmpfile"

То есть сохраните вывод во временный файл, а затем проверьте, пустой он или нет. Если он не пустой, скопируйте его содержимое в файл. В конце удалите временный файл.

Я использую, cat "$tmpfile" >myfileа не cp "$tmpfile" myfile(или mv), чтобы получить тот же эффект, который вы получили бы mycommand >myfile, то есть обрезать существующий файл и сохранить права собственности и разрешения.

Если $TMPDIR(используется mktemp) находится в файловой системе, смонтированной в памяти, то это не приведет к записи на диск иначе, чем при записи myfile. Это было бы дополнительно более портативным, чем использование ifne.

Кусалананда
источник