简体   繁体   中英

Difference between “open function” and “touch command” in Perl?

What's the difference in the below two cases for file creation.

  open(DATA,">newfile.txt");       #1.using open function
  close(DATA);

  `touch newfile.txt`;             #2.using touch command  

Which one better and fast? Note: When both open function and touch command used in Perl scripts, and the consider its used for creating empty files.

The clear difference is that in the second case you are going out to the system. A shell is started which runs the command or the command runs via execvp system call (depending on the arguments, see below). There is a lot going on, and a number of things can go wrong as well.

More importantly, there is really more to do. What if the file already exists? For one thing, open will truncate it while touch will only update timestamps. But you want a new file, so you need to check first anyway. What if this fails? You need to check. Thus this should be a little routine.

Then just write it all in Perl. There is no advantage in delegating such a simple job, only pitfalls.


Note: use three-argument open

open my $fh, '>', $file  or ...

with all requisite checks. Then you also have a much nicer lexical (indirect) filehandle to work with.


Thanks to hek2mgi for comments and to ikegami for clarifying that qx may bypass the shell depending on arguments (what appears undocumented?), much like system does.

This can be checked, per hek2mgi comment, by strace -f script.pl , where with qx(touch "NEW") in the script we find the line

[pid 24332] execve("/bin/sh", ["sh", "-c", "touch \"NEWFILE\""], [/* ...

while there is no /bin/sh in the output for qx(touch NEW) (no quotes, no shell).

To note, qx does accept an array (unmentioned in docs), which clearly gets interpolated. This is seen from output of strace -f on qx(@cmd) with @cmd = qw(ls -l > tt.out) , which has

[pid 30773] execve("/bin/sh", ["sh", "-c", "ls -l > tt.out"], [/* ...

Then a shell runs if needed (this example) and not otherwise ( qw(ls -l )), as discussed above.

*Which one better and fast?

That question makes no sense. The two snippets aren't equivalent, so you should be asking "which one of these does what I want?" The open will clobber the file if it exists, whereas touch will leave it untouched.


As for which is better between using the system call vs shelling out to run an external command, the answer is obvious if you don't leave out most of the code from the question!

Using system call directly:

utime(undef, undef, $qfn)
    or die("Can't touch \"$qfn\": $!\n");

Using system call via an external command:

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;

As you can see, shelling out is far more complicated and error prone. And of course, it's far slower to launch whole programs to make a system call instead of just making the system call.

They are two very different commands.

touch is used to modify the access and modification times of a file. By default, it set the access and modification times to the current time, and if the file doesn't exist - it will create it as an empty file.

open is for opening files for reading or writing. Depending on the mode given, the open command can also create a file if it doesn't exist.

To use touch means to invoke a separate process (a shell), so given that restriction, the open API command is preferred.

open : used for read/write.

touch : used for updating/modifying.

But, touch opens a shell by actually cloning itself (perl cloning) for running another process.

Open function is used to read/write to a file. The function uses a file descriptor and then write to the file specified. Whereas the touch function creates a new file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM