[英]How can I keep my program running when I use subprocess.call() to switch user?
[英]How can I access functions inside the anaconda3/bin directory when running a bash script with subprocess.call?
我有以下问题:我编写了一个用于数据分析的 bash 脚本,当我从终端运行它时效果很好。 为了进一步自动化该过程,我想使用运行 bash 脚本(使用 subprocess.call)、更改工作目录并重新运行脚本(等等)的 python 脚本。 当我在 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)
如果包含相关二进制文件/脚本/等的目录。 不在 output 中,那么您在 subprocess.call 创建的subprocess.call
中面临PATH
问题。
OP 在评论中确认的确切问题是anaconda3/bin
不是您的PATH
的一部分。 您的脚本在常规终端 session 中工作,因为 Anaconda 初始化 function 会在安装时添加到您的.bashrc
中。
部分答案在这里非常有用: Python - 通过 shell 脚本激活 conda env
但是,您的脚本的问题在于 .bashrc 不是由运行 shell 脚本的子shell 提供的(有关更多信息,请参见此答案)。 这意味着即使您的非登录交互式 shell 看到 conda 命令,您的非交互式脚本子外壳也不会 - 无论您调用 conda init 多少次。
正如评论中提到的OP,他们的解决方法是使用初始化 function 在他们试图运行的脚本中添加到他们的.bashrc
中。 尽管这可能感觉不是一个很好的解决方案,但这是一个“足够好”的解决方法。 不幸的是,我没有在 Linux 上使用 Anaconda,所以我没有确切的片段。 有关可能的“更清洁”解决方案,请参阅下一节。
bash -i
运行您的脚本如上面链接的相同答案中所述,您可能可以使用:
bash -i Users/.../bash_script
这将告诉bash
在交互模式下运行,然后在创建 shell 时正确地获取您的.bashrc
文件。 因此,Anaconda 和相关功能应该可以正常工作。
anaconda3/bin
到PATH
您可以查看此答案以确定这是否是您想要做的事情。 请记住,他们谈论的是 Windows 操作系统,但大多数情况同样适用于 Linux。
当您将目录添加到您的PATH
时,您明确告诉您的系统在按名称执行时始终在该目录中查找命令,例如ping
或which
。 如果您有冲突(例如在/usr/bin
和.../anaconda3/bin
中找到具有相同名称的命令),这可能会出现意外行为,因此 Anaconda 默认情况下不会将其bin
文件夹添加到您的PATH
中。
这本身不一定是“危险的”,对于大多数人来说,这不是一个理想的解决方案。 但是,您是自己系统的老板。 如果您决定这适用于您的特定工作流程,您只需将导出添加到您的脚本中:
export PATH="path/to/anaconda3/bin:$PATH"
这将设置用于当前 shell 和子进程的PATH
。
conda
source
(可能已过时) 如this answer中所述,您还可以选择手动获取conda.sh
脚本(请记住您的conda.sh
可能位于另一个目录中):
source /opt/anaconda/etc/profile.d/conda.sh
这将基本上运行 shell 脚本并将包含的功能添加到当前 shell (例如由subprocess.call
产生的功能)。
请记住,这个答案有点老(~2013),可能不再适用,这取决于conda
多年来发生了多少变化。
正如我在评论中提到的,您可能想在https://unix.stackexchange.com/上发布一些相关问题。 您有一个有趣的配置挑战,可能更适合与 Linux 相关的答案,因为您的问题直接来自 Linux shell 行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.