Как я могу вызвать awk или sed изнутри программы на c? - PullRequest
5 голосов
/ 18 марта 2009

Как я могу вызвать awk или sed внутри программы c? Я знаю, что могу использовать exec (), но я не хочу иметь дело с fork () и всей этой другой мерзостью.

Ответы [ 5 ]

7 голосов
/ 18 марта 2009

Будет ли popen работать? Он порождает процесс, а затем вы читаете / пишете с FILE* дескриптором

5 голосов
/ 18 марта 2009

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

3 голосов
/ 18 марта 2009

system () достаточно проста.

Но вы должны стараться не делать этого, если можете. Сценарии работают лучше всего, когда они на вершине, а не внизу. Если вы работаете в UNIX, часто лучше разбить работу и написать скрипт верхнего уровня для вызова всех частей.

Я помню, как программист добавлял огромное количество системных вызовов в свой C-код, чтобы избежать необходимости изучать оболочку Bourne. Он полагал, что это был умный и быстрый способ запустить его, однако, когда он потерпел неудачу, он потерпел неудачу сильно. Он потратил огромное количество времени на отладку беспорядка. Было бы намного быстрее просто выучить несколько простых команд оболочки ...

Paul.

1 голос
/ 18 марта 2009

Вы можете сделать это через системный вызов Этот поток является хорошим примером

1 голос
/ 18 марта 2009

libc имеет функции system и popen, которые работают примерно так:

int system(cont char *command) {
    const char *argv[4] = {"/bin/sh", "-c", command};
    int status;
    pid_t child = fork();
    if (child == 0) {
        execve(argv[0], argv, NULL);
        exit(-1);
    }
    waitpid(child, &status, 0);
    return status;
}

FILE *popen(const char *command, const char *type) {
    int fds[2];
    const char *argv[4] = {"/bin/sh", "-c", command};
    pipe(fds);
    if (fork() == 0) {
        close(fds[0]);
        dup2(type[0] == 'r' ? 0 : 1, fds[1]);
        close(fds[1]);
        execve(argv[0], argv, NULL);
        exit(-1);
    }
    close(fds[1]);
    return fdopen(fds[0], type);
}

(кроме случаев проверки ошибок и прочего)

Если вам нужен более точный контроль над обработкой аргументов (вместо того, чтобы проходить через sh), или вы хотите контролировать более одного из {stdin, stdout, stderr}, вам придется написать его самостоятельно или найти библиотеку. Но стандартная библиотека охватывает большинство случаев использования.

...