Как передавать команды в командной строке с помощью программы C?

Я хочу передать некоторые команды из моей программы C. Вот пример программы:

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

int main(){

    FILE *ssh = popen("ssh [email protected]", "w");

    pid_t pid;
    pid = fork();


    if(!ssh)
    {
        fprintf(stderr, "Could not open pipe for output.\n");
    } 

    if (pid==0){

        fprintf(stdout, "Child process properly created.\n");
        fputs("user", ssh); 
        fputc('\n', ssh);   // enter key 
         _exit(0);
    }


    fprintf(stdout, "Exit from child process.\n");
    pclose(ssh); 

    return 0 ;

}

Теперь, когда я запускаю эту программу, она запрашивает пароль в командной строке примерно так:

[email protected]'s password:

Я хочу передать пароль из моего примера программы, а не из командной строки. Подскажите, пожалуйста, как это сделать на C программно.

SSH используется только для примера. Это может быть и для других сценариев.

Спасибо, Юви.


person Yuvi    schedule 16.03.2012    source источник
comment
Если ваш вопрос касается ssh интерфейса, я предлагаю вам задать его на сайте superuser.com.   -  person pmg    schedule 16.03.2012
comment
Нет, это не связано с sssh   -  person Yuvi    schedule 16.03.2012
comment
Нет, это не просто связано с ssh, я взял ssh только в качестве примера. Есть много случаев, когда вы запускаете любую команду, используя системную функцию, а затем она запрашивает какой-то аргумент.   -  person Yuvi    schedule 16.03.2012


Ответы (3)


Я думаю, что команда ssh считывает пароль со своего stdin, и в этом случае вам нужно передать пароль в программу, и для этого вы можете использовать popen. Пример C99/POSIX:

#include <stdio.h>

int main()
{
    FILE *ssh = popen("ssh user@host", "w");

    fputs("p4ssw0rd", ssh);
    fputc('\n', ssh); // enter key

    pclose(ssh);
}

Непроверенный. Возможно, вам повезет больше, если вы воспользуетесь комбинацией fork/exec/dup и т. д.

person dreamlax    schedule 16.03.2012
comment
Я обновил свой код, но все равно не повезло. Cud, пожалуйста, объясните немного больше, как этого добиться, я новичок в программировании на C. - person Yuvi; 16.03.2012
comment
Я также пробовал все перестановки с комбинацией fork/exec/dup вот ссылка, по которой я перешел beej.us/guide/bgipc/output/html/multipage/index.html, но до сих пор не смог этого добиться. - person Yuvi; 19.03.2012
comment
@Yuvi: Вам не нужно разветвляться. Что произойдет, если вы запустите приведенный выше код в моем ответе без разветвления? - person dreamlax; 19.03.2012
comment
Он запрашивает пароль, как простой вызов system(). - person Yuvi; 19.03.2012
comment
@Yuvi: Хорошо, я обнаружил, что SSH определяет, подключен ли его stdin к терминалу или из канала, и если он подключен к каналу, то он не читает из него никаких данных. Если вы замените ssh user@host только на cat, вы увидите, что вы передаете текст в команду cat, а cat выведет его на терминал (точнее, на свой stdout). К сожалению, SSH не может быть написан таким образом, и это можно доказать с помощью встроенных в оболочку, например. echo "password" | ssh user@host тоже не работает, все равно просит пароль. - person dreamlax; 19.03.2012
comment
@Yuvi: В моей системе я получаю предупреждение от SSH, когда stdin не подключен к терминалу: псевдотерминал не будет выделен, потому что стандартный ввод не является терминалом. - person dreamlax; 19.03.2012
comment
Я не получаю никаких предупреждений, как вы сказали. У меня машина Linux 10.04 x86_64. Итак, есть ли какое-либо решение для этого или нет, как ранее сказал Аарон Дигулла, возможное использование вызовов fork и exec*. - person Yuvi; 20.03.2012

Это возможно, но требует гораздо больше кода. Прежде всего, вам нужно использовать fork() вместо system() плюс один из вызовов exec*(), чтобы заменить дочерний процесс командой, которую вы хотите запустить.

Для получения дополнительной информации спросите здесь или см. часто задаваемые вопросы по программированию в Unix, в частности 1. Управление процессом и 1.5 Как родительский и дочерний процессы могут обмениваться данными?

person Aaron Digulla    schedule 16.03.2012
comment
Он также хочет ввести пароль (я думаю), поэтому для этого также потребуется немного возиться с файловым дескриптором. - person dreamlax; 16.03.2012

Когда это ssh, намного проще настроить ключи ssh, поэтому вам не нужно добавлять пароль. Однако, если вы действительно хотите это сделать, это очень легко сделать с помощью API с именем expect. Я использовал это сам с хорошими результатами.

person Mike    schedule 14.03.2013
comment
Не могли бы вы отредактировать свой ответ, чтобы добавить информацию об API, который вы упомянули? - person Freakyuser; 14.03.2013