[英]Why does my Perl system call fail with dot?
I'm a beginner in Perl and I have some trouble using the "system" call. 我是Perl的初学者,在使用“系统”调用时遇到了一些麻烦。 Here is a little piece of code where I try to execute 2 shell commands : 这是我尝试执行2个shell命令的一小段代码:
# First command is :
# dot -Tpng $dottmpfile > $pngfile
# Second command is :
# rm $dottmpfile
if (!($pngfile eq "")) {
my @args = ("dot", "-Tpng", $dottmpfile, " > ", $pngfile);
system (join (' ' , @args ))
or die "system @args failed : $!";
unlink $dottmpfile;
}
EDIT : Here is my code now, and I still get an error : 编辑:这是我的代码,现在仍然出现错误:
system dot -Tpng toto.dot > toto.png failed : Inappropriate ioctl for device at /home/claferri/bin/fractal.pl line 79.
I've used system to produce this piece of code. 我已经使用系统生成了这段代码。
You are using >
to tell the shell to redirect output to a file yet by using invoking system LIST
, you are bypassing the shell. 您正在使用>
告诉外壳程序将输出重定向到文件,但是通过使用system LIST
,您正在绕过外壳程序。 Therefore, you can use: 因此,您可以使用:
system ( join (' ' , @args ) );
or 要么
system "@args";
Looking at perldoc -f system , note: 查看perldoc -f系统 ,注意:
If there is more than one argument in LIST, or if LIST is an array with more than one value, starts the program given by the first element of the list with arguments given by the rest of the list. 如果LIST中有多个自变量,或者LIST是具有多个值的数组,请启动列表中第一个元素给出的程序,并使用列表其余部分给出的参数。 If there is only one scalar argument, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing 如果只有一个标量参数,则检查该参数是否包含shell元字符,如果有,则将整个参数传递给系统的命令shell进行解析
You are invoking system LIST
so the >
ends up being passed to dot
instead of being interpreted by the shell. 您正在调用system LIST
因此>
最终将传递给dot
而不是由Shell解释。
I would recommend that you keep using system LIST
because it is a little safer than passing everything through the shell. 我建议您继续使用system LIST
因为它比将所有内容都通过外壳更安全。 According to the docs, you can specify the output file by using the -o
option to dot
, so do that. 根据文档,您可以使用-o
选项将其指定为dot
,从而指定输出文件。
If you really want to dot your i s and cross your t s (pun not intended), then you can use: 如果您确实要点i并越过t s(双关语不是故意的),则可以使用:
if ( defined $pngfile and $pngfile ne '') {
my @args = (dot => '-Tpng', $dottmpfile, "-o$pngfile");
if ( system @args ) {
warn "'system @args' failed\n";
my $reason = $?;
if ( $reason == -1 ) {
die "Failed to execute: $!";
}
elsif ( $reason & 0x7f ) {
die sprintf(
'child died with signal %d, %s coredump',
($reason & 0x7f),
($reason & 0x80) ? 'with' : 'without'
);
}
else {
die sprintf('child exited with value %d', $reason >> 8);
}
}
warn "'system @args' executed successfully\n";
unlink $dottmpfile;
}
system
returns 0 on success and non-zero on "failure". system
成功返回0,“失败”返回非零。 It's contrary to the way most of these idioms look and a little counter-intuitive, but with system
calls you should use an expression like: 这与大多数惯用语的外观和一些反直觉相反,但是对于system
调用,您应该使用类似以下的表达式:
system($command) and warn "system $command: failed $?\n"; # and not or
or 要么
if (system($command) != 0) { ... handle error ... }
Is the "dot" executable in the PATH
? PATH
的“点”可执行吗? Does it have executable permissions? 它具有可执行权限吗? Which specific error are you getting with this code? 使用此代码会遇到哪些特定错误?
It seems that is correct according to perldoc -f system . 根据perldoc -f system看来是正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.