Member 14631177 Ответов: 0

Как трубопровод `lshw` и `команда grep` команды `execv` в C?


Вот программа на языке Си, которая работает с поиском конкретных свойств, таких как информация о шине процессора, путем последовательных вызовов lshw (для доступа к общему списку оборудования с соответствующими свойствами) и grep (чтобы выбрать только соответствующий пункт среди lshw результаты):
char *strCombine(char *str1, char *str2, int n)
{
    int i = strlen(str2);
    int j = 0;
    if((str2 = (char *) realloc(str2, (i + n + 1))) == NULL)
        perror(0);
    while(j < n && str1[j])
    {
        str2[i] = str1[j];
        i++;
        j++;
    }
    str2[i] = 0;
    return (str2);
}
    
int main() 
{
    pid_t parent;
    char buf[1000] = {0};
    char *str;
    char *argv[6] = {"/usr/bin/lshw", "-C", "CPU", "|", "grep", "bus info"};       
    int fd[2];
    int ret;
    
    if(pipe(fd) == -1)
    {
        perror(NULL);
        return -1;
    }
    parent = fork();
    if(parent == 0)
    {
        close(fd[1]);
        while((ret = read(fd[0], buf, 1000)))
            str = strCombine(buf, str, ret);
        close(fd[0]);
    }
    else
    {
        close(fd[0]);
        execv(argv[0], argv);            
        close(fd[1]);
        wait(0);
    }
    wait(0);
    printf("%s", str);
    
    return 0;
}

В этом коде grep ожидается lshw так как оба идут выполняемые вызовом execv Однако этот конвейер не работает, потому что lshw ссылка на использование печатается в терминале (работает на Ubuntu 18.04 LTS) вместо bus info нужен изначально. Что делает эту программу неспособной показать только информацию, которая имеет значение, и каким образом я должен попытаться настроить конвейер?

Что я уже пробовал:

Я искал пример решения кода на любом современном языке, но ничего похожего с этим не нашел. После этого я бы попросил какую-нибудь существенную подсказку, чтобы продолжить программирование.

Richard MacCutchan

Я не думаю, что команда exec построит это как конвейер к оболочке. Вероятно, вам нужно передать параметры в оболочку в виде одной строки. Что-то вроде : char* argv[] = { "/bin/bash", "/usr/bin/lshw -C CPU | grep \"bus info\"".

0 Ответов