如何使用 Perl 写入只读文件?

how to write in read-only file using Perl?

我有一个只读文件,如果我对确认我要写入的提示回答“确定”,我可以写入该文件。我手动接受提示。

我可以使用我的 Perl 脚本做同样的事情吗?我尝试执行以下操作但最终收到错误消息“写入权限被拒绝”

my $directory= "a/b/c/d.sv";

open (my $sh, '>',"${directory}");
while($sh){
print"I am here" if(/#HERE/);
}
close $sh;

我可以覆盖这个错误吗?

您可以使用 chmod 更改文件权限并使文件可写。

权限的数字参数在 chmod man page 中进行了解释,但简而言之,您设置执行 (1)、写入 (2) 和读取 (4) 位并为所有者执行此操作,组和世界其他地区。因此,您会得到一个 3 位数字,其中第一个数字代表所有者,第二个数字代表组,最后一个数字代表世界其他地区。 0 删除所有访问权限,6 是读写访问权限(2 用于写入 + 4 用于读取)。

my $directory= "a/b/c/d.sv";
chmod 0600, $directory;
open (my $sh, '>',"${directory}");

(顺便说一句,$directory 是一个糟糕的文件名。)

如果您想将文件的权限恢复到原来的状态,您首先必须使用 stat 存储它们,其中 returns 一堆文件元信息:

my $directory= "a/b/c/d.sv";
my $oldperms = (stat($directory))[2];
printf "Old perms were %04o\n", $oldperms & 07777;
chmod 0600, $directory;
open (my $sh, '>',"${directory}");
# write the file
close $sh;
# restore old permissions
chmod $oldperms, $directory;

这是如何写入只读文件的简短版本,有关您问题的完整答案,请参阅罗伯茨的回答

#read the current permissions (and other file data if you want)
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
#temporary make the file writable
my $writablemode = 0644;
chmod($writablemode, $filename);
#do some write actions
open(my $fh, ">", $filename);
print($fh, "somedata");
close $fh;
#restore the permissions
chmod($mode, $filename);

还有另一种方法可以避免一些时间问题。

首先,在临时文件中完全创建文件。这会将原件留在原处,直到您完全完成。这还有一个安全好处,即您没有暂时取消保护文件来处理它(“竞争条件”)。而且,使用此文件的任何东西都没有机会获得不完整的

一旦您完全创建完替换文件,将其模式设置为与目标文件相同。也就是说,目标文件永远不会有不同的模式。完成后,将临时文件重命名为原始文件(不受文件权限控制,但受目录权限控制):

use File::Temp qw(tempfile);

my( $fh, $filename ) = tempfile();

print { $fh } "Hello";
close $fh;

my $target_file = $ARGV[0];
my $mode = (stat($target_file))[2];
chmod $mode, $filename;

rename $filename => $target_file;

这里有一个 shell 小脚本来演示:

TARGET_FILE=sv.txt

rm -f ${TARGET_FILE}
touch ${TARGET_FILE}
chmod 0400 ${TARGET_FILE}
ls -l ${TARGET_FILE}

perl replace.pl ${TARGET_FILE};

ls -l ${TARGET_FILE}

输出:

$ ./sv.sh
-r--------  1 brian  staff  0 Mar 31 04:14 sv.txt
-r--------  1 brian  staff  5 Mar 31 04:14 sv.txt