在使用Python的subprocess.Popen运行Perl脚本时遇到问题
我有一个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
函数都能正常工作,包括Popen
、check_output
和call
。
所以我想这主要是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 个回答
这对我来说没问题。我知道已经过了一段时间,事情可能自己就解决了。
我在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())
我在尝试从Python运行一个perl脚本时遇到了同样的错误。
我通过在我想要运行的命令中添加perl.exe的完整路径(记得加一个额外的转义字符,比如'\')来解决了这个问题,具体如下:
pipe = subprocess.Popen('C:\\Perl64\\bin\\perl myscrip.pl',shell=True,stdout=subprocess.PIPE)
pipe.stdout.read()
你可以试试用 os.system('命令') 来代替。听说这个方法不太受欢迎,或者说没有 subprocess 这么受欢迎。不过,你也可以试试 subprocess 里的其他方法,比如 call、check_call 或 check_output。我之前也遇到过类似的问题,换用这些方法中的一个就解决了。