我有一个需要用Python运行的Perl脚本,我一直在尝试使用子进程来执行它,但是没有成功。我能够让命令在命令行上运行得很好,但是子进程无法使它工作。
如果我有这样的Perl脚本:
#!/usr/bin/perl
use strict;
use warnings;
my $name = shift;
print "Hello $name!\n";
我能够在命令行上成功运行命令,如此
C:\current\path> perl test.pl world
>>>Hello world!
但是当我尝试用子进程调用相同的命令时,我得到了这个错误
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']
为子进程提供Perl的绝对路径
cmd = ['C:\path\to\perl.exe','test.pl','world']
但没有任何东西可以运作。没有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添加到子进程env,但没有任何工作。
编辑:我也无法使用该命令来处理任何其他子进程方法:check_output()
返回一个空字节字符串,call()
返回1.
任何形式的修复或替代解决方案都将受到极大的赞赏。我在Windows 7 64bit上运行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
答案 0 :(得分:0)
您可以尝试使用os.system('命令')代替。显然它由于某种原因没有得到很好的考虑,或者至少不如它被视为子进程。或者,您可以尝试一些其他子进程方法,例如call,check_call或check_output。我过去和Popen有类似的问题,转而采用其中一种方法有所帮助。
答案 1 :(得分:0)
尝试从Python运行perl脚本时遇到了同样的错误。
我设法通过将perl.exe的完整路径(带有额外的转义字符,作为'\')添加到我试图运行的命令中来实现它的工作,如下所示:
pipe = subprocess.Popen('C:\\Perl64\\bin\\perl myscrip.pl',shell=True,stdout=subprocess.PIPE)
pipe.stdout.read()
答案 2 :(得分:0)
这对我来说很好用。我知道已经有一段时间了,事情可能刚刚好转。
我使用的是 activestate perl 5.8.9
和 Windows 10 上的 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())