Как получить возвращаемое значение программы, запущенной с помощью вызова члена семейства функций exec?

Я знаю, что можно читать вывод команд с канала? Но как насчет получения возвращаемого значения? Например, я хочу выполнить:

execl("/bin/ping", "/bin/ping" , "-c", "1", "-t", "1", ip_addr, NULL);

Как я могу получить возвращаемое значение команды ping, чтобы узнать, вернуло ли оно 0 или 1?


person skujins    schedule 19.04.2010    source источник
comment
Спасибо всем за полезные и быстрые ответы.   -  person skujins    schedule 19.04.2010


Ответы (6)


Вот пример, который я написал давно. По сути, после того, как вы разветвляете дочерний процесс и wait его статус выхода, вы проверяете статус с помощью двух макросов. WIFEXITED используется для проверки нормального завершения процесса, а WEXITSTATUS проверяет возвращаемый номер в случае нормального завершения:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
    int number, statval;
    printf("%d: I'm the parent !\n", getpid());
    if(fork() == 0)
    {
        number = 10;
        printf("PID %d: exiting with number %d\n", getpid(), number);
        exit(number) ;
    }
    else
    {
        printf("PID %d: waiting for child\n", getpid());
        wait(&statval);
        if(WIFEXITED(statval))
            printf("Child's exit code %d\n", WEXITSTATUS(statval));
        else
            printf("Child did not terminate with exit\n");
    }
    return 0;
}
person AraK    schedule 19.04.2010
comment
но в этом примере я получу выход (номер); значение, возвращенное в WEXITSTATUS(statval). Как я могу определить возвращаемое значение команды ping? - person skujins; 19.04.2010
comment
Вместо выхода (число) напишите свой exec. - person Šimon Tóth; 19.04.2010
comment
но execl() не возвращает никакого значения, кроме случаев сбоя, поэтому команда ping возвращает 0 или 1 - person skujins; 19.04.2010
comment
@Skuja Как сказал Let_Me_Be, вы пишете свой exec внутри первого блока. Вы получите статус ping во втором блоке, потому что мы написали wait(&statval). Не забывайте, что вышеприведенная программа будет родителем ping в этом случае. - person AraK; 19.04.2010

Вы можете использовать waitpid, чтобы получить статус выхода вашего дочернего процесса как:

int childExitStatus;
waitpid( pID, &childExitStatus, 0); // where pID is the process ID of the child.
person codaddict    schedule 19.04.2010
comment
Просто во избежание недоразумений: статус выхода, возвращаемый waitpid(), не является кодом выхода, возвращаемым дочерней программой. Подробнее см. ответ AraK stackoverflow.com/a/2667166/694576. - person alk; 03.08.2014

exec функция familly не возвращает значение, здесь возвращается int только в том случае, если во время запуска возникает ошибка (например, не найден файл для выполнения).

Вы должны поймать возвращаемое значение из сигнала, отправленного процессу, который разветвился перед вызовом exec.

вызовите wait() или waitpid() в вашем обработчике сигналов (ну, вы также можете вызвать wait() в своем процессе без использования какого-либо обработчика сигналов, если ему больше нечего делать). делать).

person kriss    schedule 19.04.2010

Были проблемы с пониманием и применением существующих ответов.

В ответе AraK, если в приложении запущено более одного дочернего процесса, невозможно узнать, какой конкретный дочерний процесс произвел статус выхода получен. Согласно справочной странице,

ждать() и ждатьpid()

Системный вызов wait() приостанавливает выполнение вызывающего процесса до тех пор, пока не завершится один из его дочерних процессов. Ожидание вызова(&статус) эквивалентно:

       waitpid(-1, &status, 0);

   The **waitpid()** system call suspends execution of the calling process until a **child specified by pid** argument has changed state.

Итак, чтобы получить статус выхода конкретного дочернего процесса, мы должны переписать ответ как:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
    int number, statval;
    int child_pid;
    printf("%d: I'm the parent !\n", getpid());
    child_pid = fork();
    if(child_pid == -1)
    { 
        printf("could not fork! \n");
        exit( 1 );
    }
    else if(child_pid == 0)
    {
        execl("/bin/ping", "/bin/ping" , "-c", "1", "-t", "1", ip_addr, NULL);
    }
    else
    {
        printf("PID %d: waiting for child\n", getpid());
        waitpid( child_pid, &statval, WUNTRACED
                    #ifdef WCONTINUED       /* Not all implementations support this */
                            | WCONTINUED
                    #endif
                    );
        if(WIFEXITED(statval))
            printf("Child's exit code %d\n", WEXITSTATUS(statval));
        else
            printf("Child did not terminate with exit\n");
    }
    return 0;
}

Не стесняйтесь превратить этот ответ в редактирование ответа Арака.

person xor007    schedule 11.01.2015

Вы можете дождаться дочернего процесса и получить его статус выхода. Системный вызов — это wait(pid), попробуйте прочитать об этом.

person duduamar    schedule 19.04.2010

Вместо семейства exec можно использовать popen. Затем прочитайте вывод, используя fgets или fscanf.

char buff[MAX_BUFFER_SIZE];
FILE *pf = popen("your command", "r");
fscanf(pf, "%s", buff);
pclose(pf);
person Homaei    schedule 01.12.2020