sshfs代码中poll在bash返回0超时,tcsh正常的原因与解决
SSHFS中poll系统调用在不同Shell下的异常问题分析与解决
问题描述
我在使用sshfs时遇到了poll系统调用的异常行为:以下代码在tcsh环境中可正常接收输入并继续处理,但在bash环境中无法接收输入,等待60秒后触发poll的超时返回0;在嵌套shell场景(如tcsh运行于bash之上再运行tcsh)下也无法正常工作。
相关代码
while (1) { struct pollfd fds[2]; fds[0].fd = sshfs.rfd; fds[0].events = POLLIN; fds[1].fd = sshfs.ptyfd; fds[1].events = POLLIN; res = poll(fds, 2, timeout); if (res == -1) { perror("poll"); return -1; } if (res == 0) { fprintf(stderr, "Timeout waiting for prompt\n"); return -1; } if (fds[0].revents) { /* * Something happened on stdout of ssh, this * either means, that we are connected, or * that we are disconnected. In any case the * password doesn't matter any more. */ break; } res = read(sshfs.ptyfd, &c, 1); if (res == -1) { perror("read"); return -1; } if (res == 0) { fprintf(stderr, "EOF while waiting for prompt\n"); return -1; } buf[len] = c; len++; if (len == passwd_len) { if (memcmp(buf, passwd_str, passwd_len) == 0) { write(sshfs.ptyfd, sshfs.password, strlen(sshfs.password)); } memmove(buf, buf + 1, passwd_len - 1); len--; } }
差异原因分析
1. Shell的PTY输出与缓冲策略不同
- tcsh:连接到PTY后会立即输出密码提示,且输出缓冲策略更激进,无延迟输出,因此
poll能快速检测到sshfs.ptyfd上的POLLIN事件,顺利执行后续读取和密码匹配逻辑。 - bash:作为登录shell启动时,会加载
~/.bash_profile、~/.bashrc等配置文件,可能输出大量初始化内容(如欢迎信息、别名提示等),且默认采用行缓冲模式,终端未完全初始化时不会输出密码提示;加上bash对PTY的初始化流程更复杂,导致密码提示输出时机延迟,超出了poll的超时时间。 - 嵌套shell场景:外层bash已修改PTY的终端属性(如缓冲模式、终端模式),内层tcsh继承这些属性后,输出行为改变,无法像直接运行tcsh那样触发
poll的POLLIN检测。
2. 代码逻辑的依赖限制
这段代码核心逻辑依赖poll先检测到sshfs.ptyfd的可读事件(即密码提示输出),才能进入读取匹配流程。如果bash无法在超时时间内输出密码提示,poll会因检测不到任何事件而超时返回。
无需修改代码的解决方法
1. 调整bash启动配置,禁用非必要输出
编辑~/.bash_profile(针对登录shell)或~/.bashrc(针对交互式shell),添加以下内容,让bash在非标准终端环境下跳过冗余输出:
# 当终端不是交互式时,禁用所有启动输出和提示 if [[ ! -t 0 ]]; then unset PROMPT_COMMAND PS1="" # 注释或删除所有启动时会产生输出的配置(如echo语句、fortune等) fi
2. 强制bash以非交互式模式启动
修改sshfs的连接命令,指定bash以非交互式模式运行sftp-server,避免加载配置文件:
sshfs user@remote-host:/target/path /local/mount-point -o sftp_server="/bin/bash -c '/usr/lib/openssh/sftp-server'"
3. 临时调整终端属性
在启动sshfs前执行以下命令,修改终端缓冲模式,确保PTY输出能被及时检测:
stty -icanon -echo
执行完sshfs后可恢复终端属性:
stty icanon echo
内容的提问来源于stack exchange,提问作者user1818563
相关产品推荐
相关产品推荐

