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

Python 使用subprocess.call运行bash脚本时,如何访问anaconda3/bin目录中的函数?,python,linux,bash,anaconda,Python,Linux,Bash,Anaconda,我有以下问题:我编写了一个用于数据分析的bash脚本,当我从终端运行它时,它运行得非常好。为了进一步自动化这个过程,我想使用一个运行bash脚本的python脚本(使用subprocess.call)、更改工作目录并重新运行脚本(等等)。当我在我的MacBook上使用它时,它也工作得很好。但是,我需要在Linux机器上进行分析,这里出现了问题。同样,从终端运行脚本工作得很好,但一旦我尝试使用python脚本执行此操作,它就无法找到用于分析的相关函数。这些函数存储在anaconda3/bin文件夹

我有以下问题:我编写了一个用于数据分析的bash脚本,当我从终端运行它时,它运行得非常好。为了进一步自动化这个过程,我想使用一个运行bash脚本的python脚本(使用subprocess.call)、更改工作目录并重新运行脚本(等等)。当我在我的MacBook上使用它时,它也工作得很好。但是,我需要在Linux机器上进行分析,这里出现了问题。同样,从终端运行脚本工作得很好,但一旦我尝试使用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)

我只是把我的一系列评论作为一个答案,因为我认为这至少对任何遇到类似问题的人来说都是一个合理的答案(你的问题肯定很常见,可以从搜索引擎结果中检索)

问题: …从终端运行脚本效果很好,但一旦我尝试使用python脚本执行此操作,它就无法找到用于分析的相关函数

通常,您可以通过以下方法解决此类问题:

import subprocess
subprocess.call('echo $PATH', shell=True)
如果包含相关二进制文件/脚本/等的目录不在输出中,则在由
subprocess.call创建的shell中,您将面临
路径
问题

OP在评论中确认的确切问题是,
anaconda3/bin
不是您的
路径的一部分。您的脚本在常规终端会话中工作,因为安装时会将Anaconda初始化函数添加到
.bashrc

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

但是,脚本的问题在于.bashrc不是由运行shell脚本的子shell提供的(有关更多信息,请参阅)。这意味着,即使您的非登录交互shell看到conda命令,您的非交互脚本子shell也不会看到,无论您调用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操作系统,但大多数情况下同样适用于Linux

当您将目录添加到
路径
时,您特别告诉您的系统在按名称执行命令时始终在该目录中查找命令,例如,
ping
which
。如果您有冲突(例如,在
/usr/bin
../anaconda3/bin
中找到同名命令),并且默认情况下,Anaconda不会将其
bin
文件夹添加到您的
路径中,则可能会出现意外行为

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

export PATH="path/to/anaconda3/bin:$PATH"
这将设置在当前shell和子进程中使用的
路径

解决方案4:手动
source
conda
脚本(可能已过时) 如中所述,您还可以选择手动获取
conda.sh
脚本的源代码(请记住您的
conda.sh
可能位于另一个目录中):

这将基本上运行该shell脚本,并将包含的功能添加到当前shell(例如由
subprocess.call产生的功能)

请记住,这个答案已经有点过时了(~2013年),可能不再适用,这取决于多年来康达的变化程度


笔记
正如我在评论中提到的,你可能想在上发布一些相关问题。您有一个有趣的配置挑战,它可能更适合于专门针对Linux的答案,因为您的问题是直接从Linux shell行为中获取信息。

anaconda3/bin
是python产生的shell
$PATH
的一部分吗?您可以尝试一个简单的测试,如
subprocess.call('echo$PATH',shell=True)
,看看它是否存在。感谢您的回复!实际上,当我运行subprocess.call时,anaconda3/bin不是shell路径的一部分。你知道我怎样才能把它加进去吗?现在,我通过将anaconda initialize函数从bashrc脚本添加到数据分析脚本中,解决了这个问题。感觉不是理想的解决方案,但至少它是有效的。实际上,我认为使用conda initialize函数是一种更好的方法。水蟒故意制造了这种分离
source /opt/anaconda/etc/profile.d/conda.sh