我有一种情况,我需要使用我编写的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
文件(也在使用子流程进行单元测试期间)尝试了此method,但这也不起作用。
我想象的问题是,在调用每个命令之后,子进程会擦除环境,这意味着当我尝试调用它时,我的别名不存在。
如何在从Python进程启动的bash脚本中使用mock_pip
代替pip
?
答案 0 :(得分:2)
如果你的目标是提供pip的模拟实现,你可以通过以下几种方式实现:
前者是特定于shell版本的,因此我们将首先介绍后者:
subprocess.Popen('pip', env={'PATH': '/path/to/mock/dir:' + os.environ['PATH']})
...您的/path/to/mock/dir
是一个位置,其pip
可执行文件可执行您所需的操作。
后者,用于post-shellshock上游bash版本(以及之前版本的bash,其shellshock修复程序与上游到达的导出函数的协议兼容):
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
被调用