当 运行 带有 subprocess.call 的 bash 脚本时,如何访问 anaconda3/bin 目录中的函数?

How can I access functions inside the anaconda3/bin directory when running a bash script with subprocess.call?

我有以下问题:我写了一个 bash 脚本用于数据分析,当我从终端 运行 它时它工作得很好。为了进一步自动化该过程,我想使用一个 python 脚本,该脚本 运行 是 bash 脚本(使用 subprocess.call),更改工作目录,然后重新 运行s 脚本(等等)。当我在我的 MacBook 上这样做时,这也很好用。但是,我需要在 Linux 机器上进行分析,这里就出现了问题。同样,从终端 运行ning 脚本运行良好,但一旦我尝试使用我的 python 脚本执行此操作,它就无法找到用于分析的相关函数。这些函数存储在 anaconda3/bin 文件夹中。 (Python 甚至没有找到像“pip”这样的其他函数)

当然,我可以将路径添加到 bash 脚本中的所有函数,但这对我来说似乎效率很低。所以我的问题是:有没有更好的方法告诉 python 在哪里寻找函数?您能否向我解释一下为什么 运行 从终端运行脚本但在我使用 subprocess.call 时却不行?

这是 python 脚本:

import subprocess
import os

path_list = ["Path1",
             "Path2"
             ]

for path in path_list:
    os.chdir(path)
    subprocess.call("Users/.../bash_script", shell=True)

我只是 post 将我的一系列评论作为答案,因为我认为这至少构成了对 运行 遇到类似问题的任何人的合理答案(你的问题肯定是足够普遍,可以从搜索引擎结果中编制索引)。

问题:

...running the script from the terminal worked fine but once I tried doing this with my python script it fails to find the relevant functions for the analysis

一般来说,您可以通过以下方式解决此类问题:

import subprocess
subprocess.call('echo $PATH', shell=True)

如果目录包含相关binaries/scripts/etc。不在输出中,那么您在 subprocess.call 创建的 shell 中面临 PATH 问题。

OP 在评论中确认的确切问题是 anaconda3/bin 不属于您的 PATH。由于安装时添加到 .bashrc 中的 Anaconda 初始化函数,您的脚本可以在常规终端会话中运行。

部分答案在这里非常有用:

The problem with your script, though, lies in the fact that the .bashrc is not sourced by the subshell that runs shell scripts (see this answer for more info). This means that even though your non-login interactive shell sees the conda commands, your non-interactive script subshells won't - no matter how many times you call conda init.

解决方案 1:在脚本中手动使用 Anaconda 采购功能

正如 OP 在评论中提到的那样,他们的解决方法是在他们试图 运行 的脚本中使用添加到 .bashrc 的初始化函数。虽然这可能感觉不是一个很好的解决方案,但这是一个“足够好”的解决方法。不幸的是,我没有在 Linux 上使用 Anaconda,所以我没有确切的代码片段。请参阅下一节,了解可能“更清洁”的解决方案。

解决方案 2:使用 bash -i 来 运行 您的脚本

如上面链接的相同答案中所述,您可以使用:

bash -i Users/.../bash_script

这将在交互模式下告诉 bash 到 运行,然后在创建 shell 时正确地获取您的 .bashrc 文件。因此,Anaconda 和相关功能应该可以正常工作。

解决方案 3:手动将 anaconda3/bin 添加到 PATH

您可以查看 来决定这是否是您想要做的事情。请记住,他们说的是 Windows OS,但大多数相同的内容适用于 Linux.

当您将目录添加到 PATH 时,您是在明确告诉您的系统在按名称执行命令时始终在该目录中查找命令,例如pingwhich。如果您有冲突(例如,在 /usr/bin.../anaconda3/bin 中发现具有相同名称的命令),这可能会产生意外行为,因此 Anaconda 不会将其 bin 文件夹添加到您的 PATH默认。

这本身不一定是“危险的”,它只是对大多数人来说不是一个理想的解决方案。但是,您是自己系统的老板。如果您认为这适用于您的特定工作流程,您可以将导出添加到您的脚本中:

export PATH="path/to/anaconda3/bin:$PATH"

这将设置 PATH 用于当前 shell 和子流程。

解决方案 4:手动 source conda 脚本(可能已过时)

中所述,您还可以选择手动获取 conda.sh 脚本(请记住,您的 conda.sh 可能在另一个目录中):

source /opt/anaconda/etc/profile.d/conda.sh

这实际上是 运行 shell 脚本并将包含的功能添加到当前 shell(例如 subprocess.call 生成的那个)。

请记住,这个答案比较老(~2013 年),可能不再适用,具体取决于这些年来 conda 发生了多少变化。


备注

正如我在评论中提到的,您可能想 post 关于 https://unix.stackexchange.com/ 的一些相关问题。您有一个有趣的配置挑战,可能更适合专门针对 Linux 的答案,因为您的问题直接来自 Linux shell 行为。