在从 Python subprocess.Popen() 调用的脚本中模拟 shell 命令
Mock a shell command in a script called from Python subprocess.Popen()
我有一种情况需要使用我为单元测试编写的 shell 脚本 (mock_pip) 模拟可执行文件 (pip),因此我使用 subprocess 模块来获取访问权限到 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-version-specific,所以我们先介绍后者:
subprocess.Popen('pip', env={'PATH': '/path/to/mock/dir:' + os.environ['PATH']})
...您的 /path/to/mock/dir
是一个包含执行所需操作的 pip
可执行文件的位置。
后者,用于 post-shellshock upstream bash 版本(以及 bash 的先前版本 shellshock fixes 与协议兼容对于上游到达的导出函数):
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
已调用。
我有一种情况需要使用我为单元测试编写的 shell 脚本 (mock_pip) 模拟可执行文件 (pip),因此我使用 subprocess 模块来获取访问权限到 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-version-specific,所以我们先介绍后者:
subprocess.Popen('pip', env={'PATH': '/path/to/mock/dir:' + os.environ['PATH']})
...您的 /path/to/mock/dir
是一个包含执行所需操作的 pip
可执行文件的位置。
后者,用于 post-shellshock upstream bash 版本(以及 bash 的先前版本 shellshock fixes 与协议兼容对于上游到达的导出函数):
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
已调用。