Захват вывода из exec
поэтому я пытаюсь написать что-то, что нужно для захвата вывода команды, а затем плохо обрабатывать его, а затем передавать его в другую программу.
но у меня проблема, я не могу разобраться, как получить команду и сохранить ее
ниже - образец того, что у меня есть
if(fork() == 0){
execl("/bin/ls", "ls", "-1", (char *)0);
/* hopefully do something with the output here*/
}else{
*other stuff goes here*
}`
так что в основном им интересно, есть ли какой-либо способ, который я могу получить из "execl" и передать его на что-то еще (например, через его хранение в каком-то буфере).
любые предложения были бы замечательными. спасибо, ребята.. `
Ответы
Ответ 1
Вам необходимо создать канал из родительского процесса для дочернего элемента, используя pipe()
.
Затем вы должны перенаправить standard ouput
(STDOUT_FILENO) и error output
(STDERR_FILENO) с помощью dup
или dup2
в канал, а в родительском процессе - читать из канала.
Он должен работать.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define die(e) do { fprintf(stderr, "%s\n", e); exit(EXIT_FAILURE); } while (0);
int main() {
int link[2];
pid_t pid;
char foo[4096];
if (pipe(link)==-1)
die("pipe");
if ((pid = fork()) == -1)
die("fork");
if(pid == 0) {
dup2 (link[1], STDOUT_FILENO);
close(link[0]);
close(link[1]);
execl("/bin/ls", "ls", "-1", (char *)0);
die("execl");
} else {
close(link[1]);
int nbytes = read(link[0], foo, sizeof(foo));
printf("Output: (%.*s)\n", nbytes, foo);
wait(NULL);
}
return 0;
}
Ответ 2
Откройте трубку и смените stdout на соответствие этому каналу.
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int pipes[2];
pipe(pipes); // Create the pipes
dup2(pipe[1],1); // Set the pipe up to standard output
После этого все, что поступает в stdout (например, через printf), выходит из трубы [0].
FILE *input = fdopen(pipe[0],"r");
Теперь вы можете прочитать вывод как обычный дескриптор файла. Подробнее см. .
Ответ 3
Спасибо Джонатан Леффлер, и я оптимизирую вышеуказанный код, потому что он не может прочитать весь ответ за один раз.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#define die(e) do { fprintf(stderr, "%s\n", e); exit(EXIT_FAILURE); } while (0);
int main() {
int link[2];
pid_t pid;
char foo[4096 + 1];
memset(foo, 0, 4096);
if (pipe(link)==-1)
die("pipe");
if ((pid = fork()) == -1)
die("fork");
if(pid == 0) {
dup2 (link[1], STDOUT_FILENO);
close(link[0]);
close(link[1]);
execl("/bin/ls", "ls", "-1", (char *)0);
die("execl");
} else {
close(link[1]);
int nbytes = 0;
std::string totalStr;
while(0 != (nbytes = read(link[0], foo, sizeof(foo)))) {
totalStr = totalStr + foo;
printf("Output: (%.*s)\n", nbytes, foo);
memset(foo, 0, 4096);
}
wait(NULL);
}
return 0;
}