C++ shell命令提示输入密码
我想通过一个非常小的C++程序调用一些shell命令。C++ shell命令提示输入密码
诸如“git clone”或“rsync”等需要密码的命令。 例如,由于git使用SSH,这是交互式的,我无法提供密码给它。
我的程序到目前为止如下:
#include <iostream>
#include <string>
std::string ExecuteShellCommand(const std::string& cmd)
{
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe)
return std::string("ERROR");
char buffer[128];
std::string result = "";
while(!feof(pipe))
{
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
return result;
}
int main()
{
ExecuteShellCommand("git clone ssh://someurl/somerepo.git");
return 0;
}
输出:
ssh_askpass:EXEC(在/ usr /的libexec/SSH-askpass):没有这样的文件或目录
ssh_askpass: exec(/ usr/libexec/ssh-askpass):没有这样的文件或目录
ssh_askpass:exec(/ usr/libexec/ssh-askpass):没有这样的文件或目录
有没有办法让进程提示输入密码,就像直接从命令提示符执行命令一样?
谢谢!理想情况下,我要么直接在Python或Shell中执行,但我的程序需要在C++中读取不同的结构(python绑定会有点矫枉过正),所以为什么我要用C++来做到这一点。
你有两种选择。
首先,对于那些有一个,你可以使用每个程序的方法来解决这个问题。例如,git
具有GIT_ASKPASS
,并且ssh
具有基于密钥的认证。
其次,您可以使用pty
与这些程序进行通信。您可以使用程序(如expect
)或使用您自己的代码(请参阅posix_openpt
命令)执行此操作。
hummm我现在正在看posix_openpt,这对我来说有点不清楚,我应该如何使用文件描述符来打开新进程? – zedxz
在fork后,将slave pty复制到孩子的标准输入上并关闭主设备。将密码写入主站点。父母和孩子之间的pty行为类似于[管道](http://www.cs.uleth.ca/~holzmann/C/system/pipeforkexec.html) - 除了对孩子来说似乎它是一个终端。 Python有[pty.spawn和pty.fork](http://readthedocs.org/docs/python/en/latest/library/pty.html),它为你做了大部分工作。 –
我真的建议你采取大卫的使用期望的建议,尤其是在这种情况下,你应该看看libexpect http://www.tcl.tk/man/expect5.31/libexpect.3.html。它将为您处理所有这些复杂问题,并为您提供与流程沟通的直接API。有很多问题可能出现,你可能不会马上意识到,比如I/O缓冲。期待是所有这些问题的经过充分尝试的解决方案。 – frankc
考虑使用shell的脚本语言,比如batch和sh。 – orlp
@nightcracker:这是我的第一个意图,但看到我的编辑。 – zedxz