在子进程中,某些命令有效,但来自 Mac 终端的其他命令无效
In subprocess, some commands work but not others from Mac terminal
我正在尝试创建一个 python 脚本,它在 Mac 终端上运行一个 perl 脚本。流行的 3D 打印机切片引擎 Slic3r 具有使用命令行用法的能力,它是用 Perl 编写的。我想写一个 python 脚本来自动化一些流程,这是我最了解的语言。如果我直接在终端中输入我想使用的命令,它会正常工作,但是,如果我尝试使用 python 的 subprocess
,它对某些命令有效,但对其他命令无效。
例如,如果我使用我的脚本使用 docs 中概述的语法获取 Slic3r 版本,它可以正常工作。此脚本有效:
import os
import subprocess
os.system("cd Slic3r")
perl = "perl"
perl_script = "/Users/path/to/Slic3r/slic3r.pl"
params = "--version"
pl_script = subprocess.Popen([perl, perl_script, params], stdout=sys.stdout)
pl_script.communicate()
print 'done'
这个returns:
1.3.0-dev
done
如果我使用诸如 --info 之类的命令(有关更多信息,请参阅修复模型下的 Slic3r 文档)使用相同的脚本,我得到:
在:
import os
import subprocess
os.system("cd Slic3r")
perl = "perl"
perl_script = "/Users/path/to/Slic3r/slic3r.pl"
params = "--info /Users/path/to/Desktop/STL_Files/GEAR.stl"
pl_script = subprocess.Popen([perl, perl_script, params], stdout=sys.stdout)
pl_script.communicate()
print 'done'
输出:
Unknown option: info /Users/path/to/Desktop/STL_Files/GEAR.stl
Slic3r 1.3.0-dev is a STL-to-GCODE translator for RepRap 3D printers
written by Alessandro Ranellucci <aar@cpan.org> - http://slic3r.org/
Usage: slic3r.pl [ OPTIONS ] [ file.stl ] [ file2.stl ] ...
根据我的研究,我怀疑将字符串的空格用作参数存在一些问题。在尝试这个项目之前,我从未使用过 subprocess
,因此可能会出现简单的语法错误。
我知道 Slic3r 语法是正确的,因为如果我直接在终端中输入它,它就可以完美运行。有人能看出我做错了什么吗?
subprocess.Popen
接受 args
作为第一个参数。这可以是 带有完整命令(包括参数)的字符串:
args = "perl /Users/path/to/Slic3r/slic3r.pl --info /Users/path/to/Desktop/STL_Files/GEAR.stl"
pl_script = subprocess.Popen(args, stdout=sys.stdout)
或包含实际命令及其所有参数的列表(您的实际命令是perl
):
args = ["perl",
"/Users/path/to/Slic3r/slic3r.pl",
"--info",
"/Users/path/to/Desktop/STL_Files/GEAR.stl"]
pl_script = subprocess.Popen(args, stdout=sys.stdout)
后者是首选,因为它绕过了shell,直接执行了perl
。来自文档:
args
should be a sequence of program arguments or else a single
string. By default, the program to execute is the first item in args
if args
is a sequence. If args
is a string, the interpretation is
platform-dependent and described below. See the shell and executable
arguments for additional differences from the default behavior. Unless
otherwise stated, it is recommended to pass args
as a sequence.
(强调我的)
args
列表当然可以使用 Python 的标准列表操作来构建:
base_args = ["perl",
"/Users/path/to/Slic3r/slic3r.pl"]
options = ["--info",
"/Users/path/to/Desktop/STL_Files/GEAR.stl"]
args = base_args + options
args.append("--verbose")
pl_script = subprocess.Popen(args, stdout=sys.stdout)
旁注:你写了os.system("cd Slic3r")
。这将打开一个 shell,更改目录 在那个 shell,然后退出。您的 Python 脚本仍将在原始工作目录中运行。要更改它,请改用 os.chdir("Slic3r")
。 (参见 here。)
你也可以使用 shlex 分解复杂的参数,特别是在 mac 或 unix
这里有更多信息
https://docs.python.org/2/library/shlex.html#shlex.split
例如
import shlex, subprocess
args = "perl /Users/path/to/Slic3r/slic3r.pl --info /Users/path/to/Desktop/STL_Files/GEAR.stl"
#using shlex to break down the arguments
mac_arg=shlex.split(args)
#shlex.split will return all the arguments in a list
产出
['perl', '/Users/path/to/Slic3r/slic3r.pl', '--info', '/Users/path/to/Desktop/STL_Files/GEAR.stl']
这可以进一步与 Popen 一起使用
p1=Popen(mac_arg)
Shlex 主要优点是您无需担心命令,它总是会以 Popen
接受的方式拆分它们
我正在尝试创建一个 python 脚本,它在 Mac 终端上运行一个 perl 脚本。流行的 3D 打印机切片引擎 Slic3r 具有使用命令行用法的能力,它是用 Perl 编写的。我想写一个 python 脚本来自动化一些流程,这是我最了解的语言。如果我直接在终端中输入我想使用的命令,它会正常工作,但是,如果我尝试使用 python 的 subprocess
,它对某些命令有效,但对其他命令无效。
例如,如果我使用我的脚本使用 docs 中概述的语法获取 Slic3r 版本,它可以正常工作。此脚本有效:
import os
import subprocess
os.system("cd Slic3r")
perl = "perl"
perl_script = "/Users/path/to/Slic3r/slic3r.pl"
params = "--version"
pl_script = subprocess.Popen([perl, perl_script, params], stdout=sys.stdout)
pl_script.communicate()
print 'done'
这个returns:
1.3.0-dev
done
如果我使用诸如 --info 之类的命令(有关更多信息,请参阅修复模型下的 Slic3r 文档)使用相同的脚本,我得到:
在:
import os
import subprocess
os.system("cd Slic3r")
perl = "perl"
perl_script = "/Users/path/to/Slic3r/slic3r.pl"
params = "--info /Users/path/to/Desktop/STL_Files/GEAR.stl"
pl_script = subprocess.Popen([perl, perl_script, params], stdout=sys.stdout)
pl_script.communicate()
print 'done'
输出:
Unknown option: info /Users/path/to/Desktop/STL_Files/GEAR.stl
Slic3r 1.3.0-dev is a STL-to-GCODE translator for RepRap 3D printers
written by Alessandro Ranellucci <aar@cpan.org> - http://slic3r.org/
Usage: slic3r.pl [ OPTIONS ] [ file.stl ] [ file2.stl ] ...
根据我的研究,我怀疑将字符串的空格用作参数存在一些问题。在尝试这个项目之前,我从未使用过 subprocess
,因此可能会出现简单的语法错误。
我知道 Slic3r 语法是正确的,因为如果我直接在终端中输入它,它就可以完美运行。有人能看出我做错了什么吗?
subprocess.Popen
接受 args
作为第一个参数。这可以是 带有完整命令(包括参数)的字符串:
args = "perl /Users/path/to/Slic3r/slic3r.pl --info /Users/path/to/Desktop/STL_Files/GEAR.stl"
pl_script = subprocess.Popen(args, stdout=sys.stdout)
或包含实际命令及其所有参数的列表(您的实际命令是perl
):
args = ["perl",
"/Users/path/to/Slic3r/slic3r.pl",
"--info",
"/Users/path/to/Desktop/STL_Files/GEAR.stl"]
pl_script = subprocess.Popen(args, stdout=sys.stdout)
后者是首选,因为它绕过了shell,直接执行了perl
。来自文档:
args
should be a sequence of program arguments or else a single string. By default, the program to execute is the first item inargs
ifargs
is a sequence. Ifargs
is a string, the interpretation is platform-dependent and described below. See the shell and executable arguments for additional differences from the default behavior. Unless otherwise stated, it is recommended to passargs
as a sequence.
(强调我的)
args
列表当然可以使用 Python 的标准列表操作来构建:
base_args = ["perl",
"/Users/path/to/Slic3r/slic3r.pl"]
options = ["--info",
"/Users/path/to/Desktop/STL_Files/GEAR.stl"]
args = base_args + options
args.append("--verbose")
pl_script = subprocess.Popen(args, stdout=sys.stdout)
旁注:你写了os.system("cd Slic3r")
。这将打开一个 shell,更改目录 在那个 shell,然后退出。您的 Python 脚本仍将在原始工作目录中运行。要更改它,请改用 os.chdir("Slic3r")
。 (参见 here。)
你也可以使用 shlex 分解复杂的参数,特别是在 mac 或 unix
这里有更多信息 https://docs.python.org/2/library/shlex.html#shlex.split
例如
import shlex, subprocess
args = "perl /Users/path/to/Slic3r/slic3r.pl --info /Users/path/to/Desktop/STL_Files/GEAR.stl"
#using shlex to break down the arguments
mac_arg=shlex.split(args)
#shlex.split will return all the arguments in a list
产出
['perl', '/Users/path/to/Slic3r/slic3r.pl', '--info', '/Users/path/to/Desktop/STL_Files/GEAR.stl']
这可以进一步与 Popen 一起使用
p1=Popen(mac_arg)
Shlex 主要优点是您无需担心命令,它总是会以 Popen
接受的方式拆分它们