You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本无sudo时SSHFS挂载失效且无错误提示问题排查

无sudo时SSHFS挂载失效的原因及解决方法

问题描述

在WSL环境下,命令行执行sshfs -o allow_other root@192.168.122.131:/root /mnt/123可正常挂载CentOS 8服务器的目录,但通过Python脚本调用pexpect执行相同命令时,无错误提示但挂载未生效;添加sudo后脚本可正常挂载,但实际场景无法依赖sudo权限。

原因分析

1. allow_other选项的权限限制

非root用户使用allow_other选项时,默认需要满足以下条件之一,否则会静默失败:

  • 当前用户属于fuse用户组
  • 系统已在/etc/fuse.conf中开启user_allow_other配置
    这种情况下,sshfs进程会直接退出,挂载失效,但可能返回码仍为0,导致脚本无法捕获错误。

2. sshfs前台运行导致进程被终止

sshfs默认以前台模式运行,当pexpect完成交互并关闭子进程时,sshfs进程会被终止,挂载点随即被卸载。而命令行执行时,sshfs保持前台运行,挂载点不会被卸载;使用sudo时,因会话环境差异,进程未被立即终止,挂载得以生效。

解决方法

修复allow_other权限问题

选择以下任一方式:

  • 将用户加入fuse组:
    sudo usermod -aG fuse $USER
    
    执行后退出当前会话并重新登录,权限才会生效。
  • 开启user_allow_other配置:
    编辑/etc/fuse.conf,取消user_allow_other行的注释:
    sudo nano /etc/fuse.conf
    
    找到#user_allow_other,删除开头的#,保存退出后无需重启即可生效。

让sshfs后台运行,避免进程被终止

修改脚本中的命令和pexpect逻辑,让sshfs后台运行,同时调整等待逻辑:

def sshfs(ip, user, password, path_fonte, path_montado, timeout=30, bg_run=False):
    import tempfile
    import pexpect

    fname = tempfile.mktemp()
    fout = open(fname, 'w')

    # 添加-f选项让sshfs后台运行
    ssh_cmd = f"sshfs -o allow_other -f {user}@{ip}:{path_fonte} {path_montado}"
    print(ssh_cmd)
    child = pexpect.spawnu(ssh_cmd, timeout=timeout, encoding='utf-8')
    try:
        child.expect(['[pP]assword: '])
        child.sendline(password)
        # 等待几秒确认挂载完成,避免提前终止进程
        child.expect(pexpect.TIMEOUT, timeout=5)
        child.close(force=True)
    except pexpect.EOF:
        # 提前收到EOF说明挂载失败
        child.close()
        fout.close()
        fin = open(fname, 'r')
        stdout = fin.read()
        fin.close()
        raise Exception(f"挂载失败: {stdout}")
    
    fout.close()
    fin = open(fname, 'r')
    stdout = fin.read()
    fin.close()

    return stdout

if __name__ == '__main__':
    print(sshfs(ip="192.168.122.131", user="root", password="root", path_fonte="/root", path_montado="/mnt/123"))
    print(pexpect.runu("ls -l " + "/mnt/123"))

可选:使用SSH密钥认证简化流程

配置SSH密钥认证可避免密码交互的复杂性,同时提升安全性:

  1. 在WSL生成密钥对:
    ssh-keygen -t ed25519
    
  2. 将公钥复制到CentOS服务器:
    ssh-copy-id root@192.168.122.131
    
  3. 简化脚本,去掉密码交互逻辑:
    ssh_cmd = f"sshfs -o allow_other -f {user}@{ip}:{path_fonte} {path_montado}"
    child = pexpect.spawnu(ssh_cmd, timeout=timeout, encoding='utf-8')
    # 无需密码交互,直接等待确认
    child.expect(pexpect.TIMEOUT, timeout=5)
    child.close(force=True)
    

内容的提问来源于stack exchange,提问作者iml

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:16:12