文件的“就地”修改是什么意思,例如通过sed -i或perl -i意味着什么?
我的问题是关于这种就地修改是如何完成的。是复制的文件是在副本中进行修改然后替换原来的吗?或者原始文件是否以某种方式被修改到位?
Mic*_*mer 19
sed 创建一个临时文件,将输出写入该文件,然后在原始文件的顶部重命名临时文件。
您可以使用strace以下方法观察发生的情况:
$ strace -e trace=file sed -i -e '' a
execve("/usr/bin/sed", ["sed", "-i", "-e", "", "a"], [/* 34 vars */]) = 0
<...trimmed...>
open("a", O_RDONLY) = 3
open("./sedxvhRY8", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
rename("./sedxvhRY8", "a") = 0
+++ exited with 0 +++
Run Code Online (Sandbox Code Playgroud)
这会记录所有文件操作sed:它创建一个新文件(安全地使用O_CREAT|O_EXCL),将数据写入其中,然后将其移回原始文件的顶部a。
sed -i接受用于备份的后缀,在这种情况下,它首先将原始文件移开(而不是在顶部重命名)。该参数在大多数 BSD 中是强制性sed的。在这种情况下,有一段时间目录中根本没有正确名称的文件。
perl 在最近的版本中打开输入文件,然后删除它并创建一个同名的新文件:
open("a", O_RDONLY) = 3
unlink("a") = 0
open("a", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
Run Code Online (Sandbox Code Playgroud)
当您删除 ( unlink) 已打开的文件时,只要您保留句柄,您就可以保留对其的访问权限,因此它可以继续从已删除的文件中读取数据。以这种方式perl直接写入输出文件,而不是写入临时文件:不会创建其他文件,但是如果您在此过程中读取文件,您将获得部分内容,这与 withsed的方法不同。还有一小段时间没有具有正确名称的文件,这是在过程的开始而不是结束(如sed -i .bak)。
双方sed并perl会:
setgid由您不在其中且您不是 root 的组拥有,则使用您的默认组(或父目录的组,如果该目录具有该位)创建该文件。setuid和setgrp位,如果结果组与它开始的组相同。sed 将要:
perl 将要:
以上在带有 GNU 的 Linuxsed和带有它的 (FreeBSD-derived) 的 Mac OS X上都是正确的sed。