远程使用Python Fabric SSH连接服务器时如何获取正确的$PATH配置
问题1:终端SSH连接时bash加载$PATH的位置
终端SSH发起的是交互式登录shell,会按以下顺序加载配置并最终拼接成完整的$PATH:
- 系统级配置(对所有用户生效):
- 首先加载
/etc/profile - 然后加载
/etc/profile.d/目录下所有以.sh为后缀的配置文件 - 部分发行版还会同步加载
/etc/bashrc(或/etc/bash.bashrc)
- 首先加载
- 用户级配置(仅对当前登录用户生效):
- bash会按顺序查找
~/.bash_profile、~/.bash_login、~/.profile三个文件,仅加载第一个存在的文件 - 交互式shell会额外加载用户家目录下的
~/.bashrc
- bash会按顺序查找
你缺失的用户家目录bin路径、/opt下的spack、matlab等工具路径,大概率是写在用户个人配置文件或者/etc/profile.d下的自定义配置中,非登录态shell不会读取这些配置。
问题2:配置Fabric加载与终端一致$PATH的方法
Fabric默认发起的是非交互式非登录shell,只会加载最基础的系统级PATH,因此会出现路径缺失,可通过以下几种方法解决:
- 显式指定使用登录态shell
- 如果你使用的是Fabric 2.x版本,执行命令时添加
pty=True和指定登录态bash参数即可:conn.run("你要执行的命令", pty=True, shell="/bin/bash -l") - 如果你使用的是Fabric 1.x版本,在fabfile中添加全局配置:
env.shell = "/bin/bash -l -c"
- 如果你使用的是Fabric 2.x版本,执行命令时添加
- 执行命令前手动加载对应配置文件
不需要调整全局配置,仅在执行命令前source对应的配置即可,比如要加载用户个人配置就执行:conn.run("source ~/.bash_profile && 你要执行的命令")
如果是spack等全局工具的配置,source对应配置文件即可:conn.run("source /etc/profile.d/spack.sh && 你要执行的命令") - 调整.bashrc的判断逻辑
大部分发行版的~/.bashrc开头会有非交互shell直接退出的判断逻辑,你可以把自定义PATH的配置移到这段判断的前面,非交互shell也能正常读取到配置。
内容的提问来源于stack exchange,提问作者theFinestHobo
相关产品推荐
相关产品推荐

