c sshfs 使用 libexpect 通过 bash 自动连接

c sshfs automatic connection thru bash using libexpect

我想在我的 C 程序(用于 linux)中自动安装 sshfs 连接,仅使用 ssh 密码。 (我不想使用 public/private 键。)

看来我可以用 libexpect 来做。基于 this thread 似乎可以在需要时使用 libexpect 提供密码。例如,我制作了一个成功的测试程序,它使用 sudo mkdir test 创建目录,然后使用 libexpect 提供用户密码。所以那个管道看起来真的是双向的。你,使用 sshfs 和我下面的简单函数,它不起作用:我确实有一个由它生成的 sshfs 挂载,但它不起作用,我看不到文件。

enum{ASKCONTINUE,ASKPWD};

int sshfs_connect (char data[10][200], char ip[]) {

    char commandline[300];
    sprintf(commandline,"sshfs %s@%s:%s %s -p %s -o ServerAliveInterval=15",
            data[4],ip,data[6],data[5],data[7]);

    bool shouldBreak = false;

    FILE* fp = exp_popen(commandline);

    while(shouldBreak == false)
    {
        switch(exp_fexpectl(fp,
              //if asked for continuing (authenticity can't be established)
              exp_glob, "ontinue connecting (yes/no)?", ASKCONTINUE, 
              //if asked for pwd 
              exp_glob, "s password:", ASKPWD,  
              exp_end))  //
        {
            case ASKCONTINUE:
                printf("asked continue? !\n");
                fprintf(fp,"%s\n","yes");
                break;

            case ASKPWD:
                printf("asked pwd ! sending pwd: %s\n",data[8]);
                fprintf(fp,"%s\n",data[8]);
                shouldBreak = true;
                break;

            case EXP_TIMEOUT:
                shouldBreak = true;
                break;

            case EXP_EOF:
                shouldBreak = true;
                break;
        }
    }

    fclose(fp);
    return 0;

}

似乎 expect(甚至 tcl version)不能与 sshfs 一起使用,可能是因为生成的进程没有控制 tty,所以命令试图获取通过其他方式从用户那里获取密码,例如使用图形用户界面弹出窗口。

有效的方法是添加选项 -o password_stdin 以要求 sshfs 从标准输入读取密码。它在没有编写提示的情况下执行此操作,因此 libexpect 有点重量级,但是这对您应该有用:发送密码并等待 eof(这可能在默认的 10 秒超时内)。

ssh = exp_popen("sshfs -o password_stdin user@host:/dir /mntpoint");
if(ssh==NULL)fatal("fail to spawn");
fprintf(ssh, "%s\n", password);
switch(exp_fexpectl(ssh,exp_end)) {
case EXP_EOF:
    break;  // ok
case EXP_TIMEOUT:
    break;  // fail
default:
    break;  // fail
}