在使用Python的subprocess.Popen运行Perl脚本时遇到问题

0 投票
3 回答
2069 浏览
提问于 2025-04-18 17:21

我有一个Perl脚本,想用Python来运行它,但我一直在尝试用subprocess来实现,结果一直不成功。我可以在命令行上顺利运行这个命令,但subprocess却无法让它工作。

如果我有一个这样的Perl脚本:

#!/usr/bin/perl

use strict;
use warnings;

my $name = shift;

print "Hello $name!\n";

我可以在命令行上这样成功运行这个命令:

C:\current\path> perl test.pl world
>>>Hello world!

但是当我试图用subprocess调用同样的命令时,我遇到了这个错误:

cmd = 'perl test.pl world'
pipe = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
>>>"'perl' is not recognized as an internal or external command, operable program or batch file."

我尝试了不同的方式来创建cmd作为一个列表:

cmd = ['perl','test.pl','world']

并且给subprocess提供Perl的绝对路径:

cmd = ['C:\path\to\perl.exe','test.pl','world']

但都没有成功。我可以让subprocess在没有Perl的情况下正常工作:

pipe = subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE)
pipe.stdout.read()
>>>Volume in drive C is Windows7_OS....

我非常确定Perl在我的PATH中,因为正如我所说的,我可以在命令行中顺利调用这个命令。我查看了不同的帖子,建议检查os.environ["COMSPEC"],把Perl添加到subprocess的环境中,但都没有效果。

编辑:我也无法通过其他subprocess方法让命令工作:check_output()返回一个空的字节串,而call()返回1。

任何修复或替代解决方案都将非常感谢。我在Windows 7 64位上运行Python 3.4。我也尝试过32位和64位的Python,但都没有成功。


更新:我在Mac上能够让这个工作,但有一个不同之处:我不能使用shell=True。除此之外,我想用的任何subprocess函数都能正常工作,包括Popencheck_outputcall

所以我想这主要是Windows的问题。我在Windows机器上尝试不设置shell=True,但总是会遇到这个错误:

WindowsError: [Error 193] %1 is not a valid Win32 application

更新2:我还尝试创建一个.bat文件来运行这个命令,但我在尝试直接调用Perl时也遇到了同样的错误。

pipe = subprocess.Popen('test.bat',shell=True,stdout=subprocess.PIPE)
>>>"'test.bat' is not recognized as an internal or external command, operable program or batch file."

其中test.bat只有一行:

echo Hello, World

3 个回答

0

这对我来说没问题。我知道已经过了一段时间,事情可能自己就解决了。

我在Windows 10上使用的是activestate perl 5.8.9
还有python 3.9.5。

from subprocess import Popen, PIPE

proc = Popen(['perl', 'test.pl', 'world'], stdout=PIPE, stderr=PIPE)
stdout, stderr = proc.communicate()

if proc.returncode == 0:
    print(stdout.decode())
else:
    print(stderr.decode())
0

我在尝试从Python运行一个perl脚本时遇到了同样的错误。

我通过在我想要运行的命令中添加perl.exe的完整路径(记得加一个额外的转义字符,比如'\')来解决了这个问题,具体如下:

pipe = subprocess.Popen('C:\\Perl64\\bin\\perl myscrip.pl',shell=True,stdout=subprocess.PIPE)
pipe.stdout.read()
0

你可以试试用 os.system('命令') 来代替。听说这个方法不太受欢迎,或者说没有 subprocess 这么受欢迎。不过,你也可以试试 subprocess 里的其他方法,比如 call、check_call 或 check_output。我之前也遇到过类似的问题,换用这些方法中的一个就解决了。

撰写回答