[英]How to pass a value to shell script from subprocess.Popen in Python
[英]Mock a shell command in a script called from Python subprocess.Popen()
我有一种情况,我需要用我编写的shell脚本(mock_pip)模拟一个可执行文件(pip)进行单元测试,因此我使用子进程模块来访问shell。 我已经尝试了很多事情,例如:
subprocess.Popen("alias pip='/some/dir/mock_pip'", shell=True) # Create alias
subprocess.Popen("pip", shell=True) # Try to use new alias, but still points towards real pip instead
subprocess.Popen("alias pip='/some/dir/mock_pip'"; "pip", shell=True)
# Once again it uses the real pip instead of mock
我什至尝试通过更改主目录中的~/.bashrc
文件(也在使用子进程的单元测试期间)来尝试此方法 ,但这也不起作用。
我在想问题是子进程在调用每个命令之后都会擦除环境,这意味着当我尝试调用它时我的别名不存在。
我如何在我的Python进程启动的bash脚本中,使用mock_pip
代替pip
?
如果您的目标是提供pip的模拟实现,则可以采用以下几种方法:
前者是特定于shell版本的,因此我们将首先介绍后者:
subprocess.Popen('pip', env={'PATH': '/path/to/mock/dir:' + os.environ['PATH']})
... /path/to/mock/dir
是执行可执行所需操作的pip
可执行文件所在的位置。
后者,用于shellshock之后的上游bash发行版(以及具有shellshock的bash的早期版本,其修补程序与上游到达的导出函数的协议兼容):
env = dict(os.environ)
env['BASH_FUNC_pip%%'] = '() { mock_pip "$@"; }'
subprocess.Popen(['bash', '-c', 'pip'], shell=False, env=env)
注意这里的shell=False
,带有显式的['bash', '-c', ...]
-确保它是bash
(将使用导出的函数),而不是调用默认的shell sh
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.