仅在数据覆盖时覆盖文件


8

我试图用命令输出覆盖文件,但前提是有任何输出。也就是说,我通常要

mycommand > myfile

但是,如果这将myfile用空数据覆盖,我希望保留的旧版本myfile。我认为ifne应该可以使用一些东西

mycommand | ifne (cat > myfile) 

但这不起作用...

间接方法

mycommand | tee mytempfile | ifne mv mytempfile myfile

可以,但是我认为使用该临时文件是不合理的。

问:为什么我的第一个想法无效?可以工作吗?还是为我的原始问题提供了另一个不错的,也许是完全不同的解决方案?


5
“重定向到一个单独的文件,检查该文件的大小并可能对其进行重命名”对我来说似乎很简单。为什么不使用临时文件?
Jeff Schaller

Answers:


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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.