使用system()、exec()或反引号运行/scripts/pkgacct

4

我有一个小的Perl脚本,它使用system() 在cPanel中运行/scripts/pkgacct命令。代码如下:

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/");

当我运行脚本时,仅备份cPanel默认的roundcube和horde数据库。当我将system()替换为exec""时,脚本按预期运行,但是当exec被执行时立即终止,也就是说Perl脚本中的随后语句不会执行。使用反引号表现出与system()相同的行为 - 也就是不备份所有数据库。
有人能告诉我我犯了什么错误吗?
或者,如何使exec命令后面的代码仍然可以执行?

系统和执行是相似但不同的,system的行为是运行命令并等待其完成。exec的行为是运行命令并退出当前的Perl代码。所以在这种情况下,您将想要使用system。至于实际备份了什么,我不明白Perl是如何搞砸的。如果您在Perl之外单独运行/scripts/pkgacct会发生什么? - Chris Doyle
在CLI中单独运行/scripts/pkgacct可以正常工作,备份所有内容,包括数据库(由于跳过参数--skiphomedir,不包括主目录)。此外,如果我在单独的Perl脚本中运行/scripts/pkgacct作为单行语句(即除pkgacct之外没有其他语句),它也可以正常工作。 - rahuL
在你的Perl脚本中,你在哪里设置$acc_name的值?你的第一个打印语句是否显示了$acc_name的正确值?由于它在双引号中,它将在发送到系统之前进行插值。 - Chris Doyle
@ChrisDoyle - 是的,它确实有作用。那就是添加print语句的目的。 - rahuL
要在 exec 之后使剩余的代码运行,你可以使用 fork 在子进程中 exec,然后在父进程中 wait - DeVadder
你正在运行当前版本的cPanel吗?我能够在我的服务器上运行您的脚本而没有任何问题。如果可以的话,最好在服务器上运行upcp以确保所有内容都是最新的。 - Jossie B
2个回答

0

尝试像这样使用系统:

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

我发现,当你按照它期望的方式分解命令和参数时,system 函数的效果最好。


0
尝试使用 IPC::Run (https://metacpan.org/pod/IPC::Run)。你的代码应该长这样:
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/'];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接