繁体   English   中英

在从Python子进程调用的脚本中模拟shell命令.Popen()

[英]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的模拟实现,则可以采用以下几种方法:

  • 生成为导出函数
  • 将PATH值设置为指向包含包装器的目录作为可执行脚本

前者是特定于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM