0

I have the following snippet of code that I run as part of several jobs everyday:

  system("cp $keyFile  $destinationFile");
  system("chown $userID $destinationFile");
  system("chmod 400 $destinationFile");

The problem with the above code is that sometimes, very rarely, at least one of the above operations do not complete successfully and my job fails. While it is alright for the job to fail if one of the above operations fail I still want to avoid the failing one of the simple system commands.

So I have the following options:

  1. Use Perl subroutines File::Copy::copy, chmod, chown instead of the system commands.
  2. Check the return values of the system() commands. This I have done but does not explain why it might fail.

Is is better/safer to use Perl subroutines instead of system commands. My jobs will always run on an RHEL5 machine [never Windows].

Is there anything else that I can do here. How can I collect more information on what went wrong?

Update: File names or file paths will never contain spaces or weird characters. They will be from the set [a-zA-Z].

Swaranga Sarma
  • 13,055
  • 19
  • 60
  • 93
  • 1
    I assume your filenames would never contain spaces or other weird characters that might change the meaning of the cp, chown or chmod commands? – mttrb Apr 21 '12 at 06:30
  • You can capture both stdout and stderr using open3: http://perldoc.perl.org/IPC/Open3.html. Also read the faq here: http://perldoc.perl.org/perlfaq8.html#How-can-I-capture-STDERR-from-an-external-command%3f – Unos Apr 21 '12 at 07:50
  • Are these cron jobs, or are you executing them via some other mechanism? What’s insufficient about the diagnostics on the standard error from a failed command? Are you looking for a way to predict in advance whether a given `cp`, `chown`, `chmod`, or other command will fail? – Greg Bacon Apr 21 '12 at 12:14
  • @Greg Bacon.. they are executed as a cron. What I want to know is that if a copy failed, what was the reason that it failed. So that I fix the root cause of the issue. – Swaranga Sarma Apr 22 '12 at 07:36

1 Answers1

4

Yes, it's always better to use Perl native versions (File::Copy and chmod()).

Among many reasons:

  • Performance. Calling system() forks off between 1 and 2 new processes (one for command and likely another one for shell) which is a heavy operation

  • Error checking. IO related system calls in Perl set a "$!" error text variable when errors happen:

    File::Copy::copy($source, $destination)
        || die "Failed to copy from $source to $destination. Error: $!\n";
    
DVK
  • 126,886
  • 32
  • 213
  • 327
  • +1. Another general reason is portability, however this is not particularly relevant in OP's case because it is always RHE5 for him. – Gowtham Apr 21 '12 at 07:00
  • While I agree with the view of performance that is not my prime concern. Is there any extra level of debugging I can do to know why sometimes the operations might fail. – Swaranga Sarma Apr 21 '12 at 07:17
  • 1
    It's not always better. File::Copy has some serious deficiencies, for instance. – brian d foy Apr 21 '12 at 12:06
  • @Brian D Foy..can you point out some deficiencies. Or give me some relevant links. – Swaranga Sarma Apr 22 '12 at 19:00
  • You have Google just like I do, don't you? Even if you don't, it's already here on Stackoverflow. :) – brian d foy Apr 25 '12 at 16:25
  • @Swaranga Sarma - ask as a question on SO (after searching) - if it's not here it will be answered, if it's here it will get closed as duplicate pointing to answer – DVK Apr 25 '12 at 22:34