问题猛砸输出重定向 [英] Problem with Bash output redirection

查看:182
本文介绍了问题猛砸输出重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图删除除最后一行一个文件的所有行,但下面的命令没有工作,虽然file.txt的不是空的。

I was trying to remove all the lines of a file except the last line but the following command did not work, although file.txt is not empty.

$cat file.txt |tail -1 > file.txt

$cat file.txt

为什么会这样呢?

Why is it so?

推荐答案

从通过管道回到同一文件的文件重定向是不安全的;如果 file.txt的之前设置管道的最后阶段时,由外壳覆盖,尾巴开始读取关闭第一阶段,你最终空的输出。

Redirecting from a file through a pipeline back to the same file is unsafe; if file.txt is overwritten by the shell when setting up the last stage of the pipeline before tail starts reading off the first stage, you end up with empty output.

执行以下操作来代替:

tail -1 file.txt >file.txt.new && mv file.txt.new file.txt

......嗯,其实,不这样做,在生产中code;特别是如果你在一个安全敏感的环境,并以root权限运行,以下是比较合适的:

...well, actually, don't do that in production code; particularly if you're in a security-sensitive environment and running as root, the following is more appropriate:

tempfile="$(mktemp file.txt.XXXXXX)"
chown --reference=file.txt -- "$tempfile"
chmod --reference=file.txt -- "$tempfile"
tail -1 file.txt >"$tempfile" && mv -- "$tempfile" file.txt

另一种方法(避免临时文件,除非<<< 隐式地创建他们你的平台上)如下:

Another approach (avoiding temporary files, unless <<< implicitly creates them on your platform) is the following:

lastline="$(tail -1 file.txt)"; cat >file.txt <<<"$lastline"

(以上实施bash的特异性,但是在回波不情况下工作 - 例如当最后一行包含--version,例如)。

(The above implementation is bash-specific, but works in cases where echo does not -- such as when the last line contains "--version", for instance).

最后,可以使用来自 moreutils海绵

tail -1 file.txt | sponge file.txt

这篇关于问题猛砸输出重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆