如何从C程序scp?

时间:2013-09-22 17:21:13

标签: c scp

以下C程序编译并吐出“/ Users / home / tempdir”目录的目录列表。

#include <stdio.h>
#include <unistd.h>
int main(int argc, const char * argv[])
{
        execl("/bin/ls", "ls", "/Users/home/tempdir");
        // execl("/usr/bin/scp", "scp", "myfile.txt home@127.0.0.1:/Users/home/scpdir");
    return 0;
}

这表明可以从C程序执行二进制文件。我试图弄清楚如何执行“scp”二进制文件并输入所需的密码。如何通过scp修改上述代码以实现成功的文件传输?

我尝试了上面注释掉的行但是当它被取消注释时我得到以下消息:

usage: scp [-1246BCEpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
           [-l limit] [-o ssh_option] [-P port] [-S program]
           [[user@]host1:]file1 ... [[user@]host2:]file2

所以它显然是在没有密码的情况下尝试执行scp。我该如何解决这个问题?

4 个答案:

答案 0 :(得分:4)

虽然您可以使用expect或者某些东西从命令行调用scp,但如果可能的话,最好还是使用库。

开发时的一般规则是尽可能优先选择库进行系统执行。它使您的代码更清洁,更便携。例外情况是您正在编写shell脚本。

http://www.libssh2.org/

libssh2是一个免费的C库,支持密码验证以及SCP / SFTP并支持OS X.

http://curl.haxx.se/libcurl/

libcurl几乎支持您可能想要的每种文件传输类型,几乎可以处理您想要的每个平台,并且几乎可以为您所需的每种语言提供绑定。

答案 1 :(得分:1)

简短的回答,我知道,但您通常会使用类似Expect的内容来以这种方式自动化交互式应用程序。

答案 2 :(得分:0)

在我看来,您正在打印的输出来自不正确的命令语法。根据execl的手册页(至少在Arch Linux上):

  

execl(),execlp()中的const char * arg和后续省略号,   和execle()函数可以被认为是arg0,arg1,...,argn。

因此,调用它的正确方法似乎是:

execl("/usr/bin/scp", "scp", "myfile.txt", "home@127.0.0.1:/Users/home/scpdir");

此外,如果您想避免完全输入密码,可以使用“授权密钥”配置SSH(scp构建在其上),该密钥可以绕过密码。不过,它可能仍会询问未知的关键指纹。 设置无密码scp访问的简单方法是运行(从启动scp的计算机):

ssh-copy-id home@127.0.0.1

上面的命令会要求输入一次密码,在后续的ssh操作中你不需要再输入密码。

答案 3 :(得分:0)

以下代码对我有用:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    execl("/usr/bin/scp", "scp", "myfile.txt", "user@IP:path/to/file", (char *)0);
    return 0;
}