【发布时间】:2021-08-02 22:45:05
【问题描述】:
我是 Perl 的初学者,所以如果我的问题很琐碎,请多多包涵。
我正在尝试修复一个相当大的 Perl 项目中的错误。通过一些试验和错误以及打印语句,我可以确定以下对 imagemagick 的系统调用是导致该错误的原因:
system(
composite => $tmpfilename,
-gravity => $gravity_combo->get_active_text,
$filename => $tmpfilename2
);
代码执行仅在此系统调用处停止并且不发出任何输出。偶然地,当试图从这个系统调用中获取一些输出时,我发现如果我用下面的替换系统调用
my $command = "composite " . $tmpfilename . " -gravity " . $gravity_combo->get_active_text . " " . $filename . " " . $tmpfilename2;
my $output = `$command`;
命令执行成功。
如您所见,逗号和 => 箭头被字符串连接替换,system() 被反引号替换,但除此之外,命令是相同的。
现在我想知道这是怎么发生的,是否有更优雅的方式来编写命令。
附录:
我不想分享完整的代码,因为一方面它是一个有点流行的应用程序的代码,我不想给人一种像我这样的业余爱好者正在开发它的印象(我是无论如何都不是开发人员,只是主要处理错误跟踪器上的用户支持的团队成员);另一方面,我没想到在这种情况下更多的上下文会有所帮助。但是由于一些用户要求更多的上下文,而且问题似乎比我最初想象的要复杂得多,所以我将提供完整的代码。
有问题的代码来自 Linux 桌面截图工具 Shutter 的插件。整个项目可以在https://github.com/shutter-project/shutter找到,具体的插件在https://github.com/shutter-project/shutter/blob/master/share/shutter/resources/system/plugins/perl/spwatermark/spwatermark
启动插件时,会显示一个对话框,用户可以在其中输入一些字段。对话框如下所示:
当第一次启动它时,它会执行函数fct_imagemagick_watermark()(从第254行开始)。每当单击刷新或保存按钮时,都会发送一个重新启动此功能的信号(信号在第 164 行和第 167 行发送)。在函数内部,调用了一个子函数apply_effect(),它从第 341 行开始,在第 354 行和第 365 行包括对 imagemagick 命令的两个系统调用。实际上,当通过刷新或保存按钮调用函数时,两个系统调用都会失败,但是命令如果它们是使用反引号和连接点编写的,则可以使用。
$gravity_combo->get_active_text 是对话框右上角下拉菜单的值(例如,“Center”)。在第 227 行左右生成了两个 tmpfilename 变量,filename 变量来自主程序。
到此为止我对代码的理解就这么多了,如果还有问题,请再问!
附录2:原始问题中系统调用中变量的可能值:
$tmpfile = /tmp/euQgBTRpnf.png
$tmpfile2 = /tmp/eftbUp8eNf.png
$filename = /home/user/myimage.png
$gravity_combo = Gtk3::ComboBoxText=HASH(0x55e315db9568)
$gravity_combo->get_active-text = "Center"
【问题讨论】:
-
什么操作系统?
composite是否输出要在$output中捕获的任何内容?你应该检查system的返回值。 -
system不会捕获任何输出,这与反引号(或qx()相同)不同。然而,它应该在 shell 中执行相同的命令,这可能在 Perl 之外产生一些影响。大概这不是错误的根源,因为正如您所说,命令是相同的。什么是错误? -
改用
system('composite', $tmpfilename, '-gravity', $gravity_combo->get_active_text, $filename, $tmpfilename2);。 -
@choroba:Linux(更准确地说是 Arch Linux)。
-
@TLP:它是一个 GUI 应用程序,特别具有“刷新”和“保存”按钮。首次启动时,它会执行一个包含此系统调用的函数,这会成功。但是当我点击“刷新”或“保存”按钮时,它应该再次启动该功能,该操作没有执行并且GUI关闭。我用打印语句(系统之前的打印语句)跟踪它call 被执行,之后的那个不是当一个按钮被点击时;在初始启动时两者都被执行)。
标签: perl