4

I have a small perl script which runs the /scripts/pkgacct command in cPanel using system(). The code looks like so;

print  "\n/scripts/pkgacct --skiphomedir --nocompress $acc_name /my_backup\n\n";
system("/scripts/pkgacct --skiphomedir --nocompress $acc_name /my_backup");
my $bk_path = "/my_backup/cpmove-$acc_name.tar";
system("tar -xvf $bk_path -C /my_backup/");

When I run the script, only cPanel's default roundcube and horde databases are backed up. When I replace system() with exec"", the script runs as expected but terminates as soon as exec is executed, i.e the subsequent statements in the perl script aren't executed. Using backticks shows the same behaviour as system() - i.e doesn't backup all the databases.

Could someone tell me what mistake I am making?

Alternately, how can I get the remaining statements to execute after the exec command?

rahuL
  • 3,330
  • 11
  • 54
  • 79
  • System and execute are similar but not the same, the behaviour of system is to run the command and wait for it to finish. the behavior of exec is to run the command and exit the current Perl code. So in this case you will want to use system. As for what actually gets backed up, I don't see how Perl is messing this up. What happens if you run the /scripts/pkgacct on its own outside of Perl? – Chris Doyle Oct 21 '13 at 08:19
  • Running `/scripts/pkgacct` on it's own from the CLI works as expects backs up everything including the databases (except the home dir due to the skip argument --skiphomedir). Also, if I run the `/scripts/pkgacct` as a single line within a separate perl script, (i.e. No other statements apart from pkgacct), it works as expected. – rahuL Oct 21 '13 at 08:25
  • where do you set the value of $acc_name in your perl script? Does your first print statement show the correct value for $acc_name? Since its in double qoutes it will be interpolated before being sent to they system. – Chris Doyle Oct 21 '13 at 08:30
  • @ChrisDoyle - Yes, it does. That was the purpose of adding that `print` statement. – rahuL Oct 21 '13 at 08:51
  • To get the remaining code to run after an `exec` you could `fork`, `exec` in the child and `wait` in the parent. – DeVadder Oct 21 '13 at 10:46
  • Are you running the current version of cPanel? I was able to run your script on my server without an issue. Probably wouldn't hurt to run an upcp on the server (if you can) to ensure it's all up to date. – Jossie B Oct 21 '13 at 20:40

2 Answers2

0

Try using system like so:

system('/scripts/pkgacct', '--skiphomedir', '--nocompress', $acc_name, '/my_backup');

I've found that system works best when you break up the command and parameters like it expects.

Matthew Lenz
  • 332
  • 4
  • 8
0

Try using IPC::Run (https://metacpan.org/pod/IPC::Run). Your code would look something like:

use IPC::Run qw(run);

print  "\n/scripts/pkgacct --skiphomedir --nocompress $acc_name /my_backup\n\n";
run ['/scripts/pkgacct', '--skiphomedir', '--nocompress', $acc_name];
my $bk_path = "/my_backup/cpmove-$acc_name.tar";
run ['tar','-xvf',$bk_path,'-C','/my_backup/'];
szabgab
  • 6,202
  • 11
  • 50
  • 64
joehep
  • 136
  • 1
  • 5