Timpa file hanya jika data

8

Saya mencoba untuk menimpa file dengan output perintah, tetapi hanya jika ada output. Artinya, saya biasanya mau

mycommand > myfile

tetapi jika ini akan ditimpa myfiledengan data kosong, saya ingin mempertahankan versi lama myfile. Saya pikir sesuatu menggunakan ifneharus mungkin, a la

mycommand | ifne (cat > myfile) 

tapi itu tidak berhasil ...

Pendekatan tidak langsung

mycommand | tee mytempfile | ifne mv mytempfile myfile

berfungsi, tapi saya menganggap penggunaan file temp tidak memenuhi syarat.

T: Mengapa ide pertama saya tidak berfungsi? Bisakah ini dibuat bekerja? Atau adakah solusi lain yang bagus dan mungkin sama sekali berbeda untuk masalah awal saya?

Hagen von Eitzen
sumber
5
"Mengarahkan ke file terpisah, memeriksa ukuran file itu dan mungkin mengganti nama" tampaknya cukup mudah bagi saya. Mengapa tidak menggunakan file sementara?
Jeff Schaller

Jawaban:

18

Pendekatan pertama Anda berhasil, Anda hanya perlu memberikan perintah kepada ifne(lihat 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.

Jadi, Anda perlu memberikan perintah untuk menjalankannya. Anda hampir sampai, teeakan bekerja:

command | ifne tee myfile > /dev/null

Jika perintah Anda tidak menghasilkan data dalam jumlah besar, jika cukup kecil untuk ditampung dalam sebuah variabel, Anda juga bisa melakukannya:

var=$(mycommand)
[[ -n $var ]] && printf '%s\n' "$var" > myfile
terdon
sumber
8

Solusi pejalan kaki:

tmpfile=$(mktemp)

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

rm -f "$tmpfile"

Yaitu, simpan output ke file sementara, lalu uji apakah itu kosong atau tidak. Jika tidak kosong, salin isinya ke file Anda. Pada akhirnya, hapus file sementara.

Saya menggunakan cat "$tmpfile" >myfiledaripada cp "$tmpfile" myfile(atau mv) untuk mendapatkan efek yang sama seperti yang Anda dapatkan mycommand >myfile, yaitu untuk memotong file yang ada dan mempertahankan kepemilikan dan izin.

Jika $TMPDIR(digunakan oleh mktemp) pada sistem file yang terpasang di memori, maka ini tidak akan menulis ke disk selain dari kemungkinan saat menulis myfile. Selain itu akan lebih portabel daripada menggunakan ifne.

Kusalananda
sumber