Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > shell из программы


Автор: devmstr 9.11.2006, 22:47
Я новичек в программировании под Unix(Linux), поэтому не пинайте меня очень сильно.
Как мне из своей C программы выполнить какою-нибудь команду, ну например ls, и получить обратно результат. Помогите, пожайлуста.

Автор: BobiKK 9.11.2006, 23:02
Наверное, стандартный механизм fork-and-exec. Поищите какие-нибудь статейки по этому ключевому слову. Наверняка там будет лучше и глубже расписан этот механизм, чем здесь расскажут.

Автор: MAKCim 9.11.2006, 23:50
devmstr, 
кратко
Код

...

int pipefd[2];
pipe(pipefd);

pid_t pid = fork();

if (pid > 0) {
    close(pipefd[1]);
/* тут читаем с pipefd[0] вывод ls */
    waitpid(pid, NULL, 0);

    close(pipefd[0]);
}

else if (pid < 0);      /* Error */

close(pipefd[0]);
/* Child process */
dup2(pipefd[1], 1);

execlp("ls", "ls", "/", NULL);


Автор: Dude03 10.11.2006, 01:29
Цитата(devmstr @  9.11.2006,  22:47 Найти цитируемый пост)
Я новичек в программировании под Unix(Linux), поэтому не пинайте меня очень сильно.
Как мне из своей C программы выполнить какою-нибудь команду, ну например ls, и получить обратно результат. Помогите, пожайлуста. 

Если тебе не надо чисто на системных вызовах, то можешь попробовать функцию system из стандартной библиотеки си. Вроде нао подключить stdlib.h smile 

Автор: MAKCim 10.11.2006, 11:15
можешь еще popen, pclose попробовать
Код

FILE* fs = popen("ls /", "r");

if (fs == NULL) {
/* error */
}

size_t bytes;

char buf[BUF_SIZE];

while ((bytes = fread(buf, sizeof(char), BUF_SIZE, fs)) > 0) {
/* work with buffer `buf' */
}

pclose(fs);

Автор: BobiKK 10.11.2006, 15:46
Цитата(Dude03 @  10.11.2006,  01:29 Найти цитируемый пост)
Если тебе не надо чисто на системных вызовах, то можешь попробовать функцию system из стандартной библиотеки си. Вроде нао подключить stdlib.h

А как через system получить результат выполения программы?

Автор: devmstr 11.11.2006, 10:20
MAKCim
Громадное спасибо. Именно то, что мне нужно. Взяв за основу ваш пример и разобравшись в том, что мне нужно использовать fork и execlp я написал свой. Все работает.
А можно вопрос по Вашему листингу? Какое предназначение 
Код

pipefd; и pipe(pipefd);
??

Автор: MAKCim 11.11.2006, 10:39
Цитата

А можно вопрос по Вашему листингу? Какое предназначение 

cоздание канала
грубо говоря создание буфера обмена между двумя родственными процессами
pipe() возвращает 2 дескриптора - на запись и на чтение, собственно эти операции (read/write на дескрипторах) синхронизируются ядром, потому канал - хороший способ взаимодествия дочернего и родительского процессов при передаче небольших по объему данных (буфер канала обычно не сильно велик)
Если в примере не использовать канал - весь вывод ls пойдет на STDOUT_FILENO (по умолчанию либо терминал, либо псевдотерминал для X) и мы не сможем обработать вывод

Автор: vdim 10.9.2008, 05:39
А могут ли способы через popen либо через execlp передать более чем 4096 байт?

Автор: MAKCim 10.9.2008, 07:38
Цитата(vdim @  10.9.2008,  05:39 Найти цитируемый пост)
А могут ли способы через popen либо через execlp передать более чем 4096 байт? 

могут

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)