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
}
我想在我的 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
}