[英]Difference between “open function” and “touch command” in Perl?
以下两种文件创建情况有什么区别。
open(DATA,">newfile.txt"); #1.using open function
close(DATA);
`touch newfile.txt`; #2.using touch command
哪个更好更快? 注意:当 Perl 脚本中同时使用 open 函数和 touch 命令时,考虑它用于创建空文件。
明显的区别在于,在第二种情况下,您将进入系统。 启动一个 shell 来运行命令或命令通过execvp
系统调用运行(取决于参数,见下文)。 有很多事情正在发生,很多事情也可能出错。
更重要的是,还有很多事情要做。 如果文件已经存在怎么办? 一方面, open
会截断它,而touch
只会更新时间戳。 但是您想要一个新文件,因此无论如何您都需要先检查。 如果这失败了怎么办? 你需要检查一下。 因此,这应该是一个小程序。
然后只需用 Perl 编写所有内容。 委派这么简单的工作没有任何好处,只有陷阱。
注意:使用三参数open
open my $fh, '>', $file or ...
进行所有必要的检查。 然后,您还有一个更好的词法(间接)文件句柄可以使用。
感谢hek2mgi的评论和ikegami澄清qx可能会根据参数绕过 shell(什么似乎没有记录?),就像系统一样。
这可以根据hek2mgi注释通过strace -f script.pl
进行检查,其中在脚本中使用qx(touch "NEW")
可以找到该行
[pid 24332] execve("/bin/sh", ["sh", "-c", "touch \"NEWFILE\""], [/* ...
而qx(touch NEW)
的输出中没有/bin/sh
(没有引号,没有外壳)。
需要注意的是, qx
确实接受一个数组(在文档中未提及),它显然是内插的。 这可以从strace -f
on qx(@cmd)
with @cmd = qw(ls -l > tt.out)
输出中看出,它具有
[pid 30773] execve("/bin/sh", ["sh", "-c", "ls -l > tt.out"], [/* ...
然后,如果需要(此示例)而不是其他情况( qw(ls -l
)),则 shell 会运行,如上所述。
*哪个更好更快?
这个问题没有意义。 这两个片段并不等效,因此您应该问“其中哪一个可以满足我的要求?” 如果文件存在,则open
将破坏文件,而touch
将保持不变。
至于使用系统调用与外壳运行外部命令哪个更好,如果您不遗漏问题中的大部分代码,答案是显而易见的!
直接使用系统调用:
utime(undef, undef, $qfn)
or die("Can't touch \"$qfn\": $!\n");
通过外部命令使用系统调用:
use String::ShellQuote qw( shell_quote );
my $cmd = shell_quote("touch", "--", $qfn);
my $output = `$cmd 2>&1`;
die("Can't touch \"$qfn\": Killed by signal ".($? & 0x7F)."\n" if $? & 0x7F;
die("Can't touch \"$qfn\": Exited with error ".($? >> 8).": $output" if $? >> 8;
如您所见,炮击要复杂得多,而且容易出错。 当然,启动整个程序来进行系统调用而不是仅仅进行系统调用要慢得多。
它们是两个非常不同的命令。
touch
用于修改文件的访问和修改时间。 默认情况下,它将访问和修改时间设置为当前时间,如果文件不存在 - 它会将其创建为一个空文件。
open
用于打开文件以进行读取或写入。 根据给定的模式,如果文件不存在, open 命令也可以创建文件。
使用touch
意味着调用一个单独的进程(一个 shell),因此考虑到这个限制, open
API 命令是首选。
open
: 用于读/写。
touch
: 用于更新/修改。
但是, touch
通过实际克隆自身(perl 克隆)来运行另一个进程来打开一个 shell。
Open 函数用于读/写文件。 该函数使用文件描述符,然后写入指定的文件。 而触摸功能会创建一个新文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.