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

如何使用Perl编写只读文件?,perl,Perl,我有一个只读文件,如果我对确认我要写入的提示回答ok,我可以写入该文件。我手动接受提示 我可以使用Perl脚本执行同样的操作吗?我尝试执行以下操作,但最终得到一个错误“写入权限被拒绝” 我可以覆盖此错误吗?您可以使用更改文件权限并使文件可写 中解释了权限的number参数,但简而言之,您设置了execute(1)、write(2)和read(4)位,并为所有者、组和世界其他地方执行此操作。所以你会得到一个三位数的数字,其中第一位数字代表所有者,第二位代表团体,最后一位代表世界其他地方。0删除所有

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

我可以使用Perl脚本执行同样的操作吗?我尝试执行以下操作,但最终得到一个错误“写入权限被拒绝”

我可以覆盖此错误吗?

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

中解释了权限的number参数,但简而言之,您设置了execute(1)、write(2)和read(4)位,并为所有者、组和世界其他地方执行此操作。所以你会得到一个三位数的数字,其中第一位数字代表所有者,第二位代表团体,最后一位代表世界其他地方。0删除所有访问权限,6为读写访问权限(2为写入,4为读取)

my$directory=“a/b/c/d.sv”;
chmod0600$目录;
打开(my$sh,'>',“${directory}”);
(顺便说一句,
$directory
是一个糟糕的文件名。)

如果要将文件的权限恢复为以前的权限,首先必须使用存储权限,这将返回一组文件元信息:

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;

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

#读取当前权限(以及其他文件数据,如果需要)
my($dev、$ino、$mode、$nlink、$uid、$gid、$rdev、$size、$atime、$mtime、$ctime、$blksize、$blocks)=stat($filename);
#临时设置使文件可写
my$writablemode=0644;
chmod($writeablemode,$filename);
#做一些写动作
打开(我的$fh,“>”,$filename);
打印($fh,“某些数据”);
收盘价$fh;
#恢复权限
chmod($mode,$filename);

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

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

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

下面是一个小的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

如果要提示用户,为什么要使用
die
?更改文件是否为只读是特定于系统的。Win还是Unix?一切都在Linux中。谢谢Robert!知道了。是的,我一定要更改文件名。请注意,这会暂时取消对文件的保护,因此会有一个短窗口,在此期间其他内容可能会干扰文件。这不会显示如何写入只读文件。哦,你说得对,我忘记了最重要的行…5秒钟前在编辑中修复
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