【问题标题】:Mock a shell command in a script called from Python subprocess.Popen()在从 Python subprocess.Popen() 调用的脚本中模拟 shell 命令
【发布时间】:2023-04-04 06:50:02
【问题描述】:

我有一种情况,我需要使用我为单元测试编写的 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 文件(也在使用子进程进行单元测试期间)尝试了这个method,但这也不起作用。
我想问题是子进程在调用每个命令后都会擦除环境,这意味着当我尝试调用它时我的别名不存在。

如何在从我的 Python 进程启动的 bash 脚本中使用 mock_pip 而不是 pip

【问题讨论】:

  • 您发布的代码包含语法错误。也许你可以在设置shell=True 时让它工作,但我想它不会适用于不同的 popens。为什么不创建一个调用适当 pip 的 python 函数?
  • subprocess 不会擦除环境,操作系统会。将别名添加到.bashrc,但别名通常不会在脚本中扩展,它们是支持的噩梦,通常被认为是不好的做法(首选函数),你必须shopt -s expand_aliases(同样,在.bashrc)。
  • @syntonym 对不起,我忘了校对我的代码,但我确实有 shell=True。你是什​​么意思创建一个函数来调用适当的 pip 呢?
  • 您可以将更新后的环境与 PATH 更改放在您的 subprocess.Popen() 参数列表本身中。 subprocess.Popen(..., env={'PATH': '/directory/with/new/stub:' + os.environ['PATH']})
  • 顺便说一句,我建议修改您的问题,以便询问您真正有兴趣了解什么——即。从 Python 的subprocess.Popen 调用时如何模拟 shell 命令,而不是关于别名持久性。

标签:
python
bash
shell
subprocess