PYTHONPATH setting inside python script using subprocess.Popen() fails
如果自定义模块不在sys.path变量的任何目录中,下面的代码允许我动态地标识和加载该模块。
1 2 | import sys sys.path.append("/lib") |
但是,这给了我一个错误
1 2 | import subprocess x = subprocess.Popen(["export","PYTHONPATH=/lib"], stdout=subprocess.PIPE) |
不仅如此,甚至简单的linux/unix变量声明设置也会在subprocess.popen()中失败。
1 2 | import subprocess x = subprocess.Popen("x=y", stdout=subprocess.PIPE) |
我想检查子进程,因为我试图通过os.system()、os.popen()等设置pythonpath,但变量没有设置(可能是在子进程shell中设置的)。
这里发生了一些事情,可能会让你有点困惑。一件事是,给popen的任何指令都将在子进程中执行,不会影响主进程。您只能通过管道或从中检索结果。
首先对第二个用例进行注释,其中使用字符串作为参数。从文档中可以看到:
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None,
stdout=None, stderr=None, preexec_fn=None, close_fds=True,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0, restore_signals=True,
start_new_session=False, pass_fds=())
…
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.On POSIX, if args is a string, the string is interpreted as the name
or path of the program to execute. However, this can only be done if
not passing arguments to the program.
因此,在第二种情况下,您试图执行一个文件或程序x=y,但它不起作用。
即使您像在第一个用例中那样使用list,您也必须知道,这并不等同于向bash shell传递代码。如果需要,可以使用shell=true作为关键字参数,但这还有文档指出的其他问题。但您的代码将以shell=true执行。
如果您的唯一目的是设置环境变量,那么您应该考虑使用将环境变量映射到值的os.environ变量(如@cdarke所示)。
试试这个:
1 2 3 4 | >>> subprocess.call(["export foo=bar && echo foo=$foo"], shell=True) foo=bar 0 >>> |