C 组合系统()和popen()?

C 组合系统()和popen()?,c,system,C,System,编辑2:仔细想想,这里可能有个更好的问题: 如果我使用popen写入sysfs文件,它会阻塞直到写入完成,但不会等待sysfs文件完成处理。我怎样才能等待sysfs文件执行它正在执行的任何操作 我想在程序中运行一个命令,等待它完成(需要几秒钟),然后将终端输出返回给我,而不将其打印到控制台 通过阅读其他问题,我发现可以使用system()或exec()调用来运行命令。然而,这些并没有给你终端的输出,所以你需要做一些笨拙的事情,比如写一个文件,然后打开并读取该文件,然后删除它 我看到的另一个选项是

编辑2:仔细想想,这里可能有个更好的问题:

如果我使用popen写入sysfs文件,它会阻塞直到写入完成,但不会等待sysfs文件完成处理。我怎样才能等待sysfs文件执行它正在执行的任何操作

我想在程序中运行一个命令,等待它完成(需要几秒钟),然后将终端输出返回给我,而不将其打印到控制台

通过阅读其他问题,我发现可以使用
system()
exec()
调用来运行命令。然而,这些并没有给你终端的输出,所以你需要做一些笨拙的事情,比如写一个文件,然后打开并读取该文件,然后删除它

我看到的另一个选项是
popen()
,它提供了一个可用于获取终端输出的文件描述符。然而,这似乎并没有等待命令完成,这导致我的程序有点出错

那么,我如何才能在强制popen等待子进程完成后再执行其他操作的同时获得popen的功能呢

编辑:以下是我目前正在做的事情:

#include <stdio.h>

int main(){
    FILE *file;
    char terminal[512];

    sprintf(terminal,"/bin/cat /home/Config/BASE_SETTINGS.bin > /sys/bus/iio/devices/iio\:device3/profile_config");
    if(!(file=popen(terminal,"r"))){return -1;}
    while(fgets(terminal,sizeof(terminal),file)!=NULL){
        printf("%s\n", terminal);
    }
    pclose(file);
}
#包括
int main(){
文件*文件;
字符终端[512];
sprintf(终端,“/bin/cat/home/Config/BASE_SETTINGS.bin>/sys/bus/iio/devices/iio\:设备3/profile_Config”);
if(!(file=popen(terminal,“r”)){return-1;}
while(fgets(终端,sizeof(终端),文件)!=NULL){
printf(“%s\n”,终端);
}
pclose(文件);
}
这是程序的一部分,我做了几次同样的事情,每次都只是更改“sprintf”中的命令。据我所知,pclose应该阻止。但是,当我从终端运行该命令时,在写入sysfs文件几秒钟后,它才完成配置。然而,当我通过程序执行此操作时,程序运行不到一秒钟

因为我的程序中后面的命令依赖于正在配置的sysfs驱动程序,并且在sysfs进程完成之前,它似乎要执行后面的命令,所以后面的命令会失败,因为它们最终会在配置完成之前运行。

pclose()和_pclose()(在windows上)将一直阻止,直到子流程的执行完成。要获得输出,只需使用文件指针打开它们,然后使用fgets读取它们。请参见以下示例(适用于win32和unix系统):

#包括
#包括
#包括
#如果已定义(_WIN32)
#包括
#否则
#包括
#恩迪夫
#ifndef路径_最大值
#定义路径\u MAX 255//通常在中定义
#恩迪夫
文件*popenHandler(常量字符*args,常量字符*方法)
{
#如果已定义(_WIN32)
返回_popen(参数,方法);
#否则
返回popen(args,method);
#恩迪夫
}
int pcloseHandler(文件*fp)
{
#如果已定义(_WIN32)
返回(fp);
#否则
返回pclose(fp);
#恩迪夫
}
int main()
{
FILE*fp;//指向命令的文件指针
char path[path_MAX];//用于存储输出的字符缓冲区
#如果已定义(_WIN32)
char命令[PATH_MAX]=“dir”;//要执行的命令
#否则
char命令[PATH_MAX]=“ls-l”;//要执行的命令
#恩迪夫
//如果要在结果中包括stderr,请取消对以下字符串的注释
//strncpy(命令,“2>&1”,路径_MAX);//将stderror与stdout合并
fp=popenHandler(命令,“r”);//在win32或unix上工作的函数
如果(fp==NULL){
printf(“错误:无法执行命令%s\n”,命令);
返回-1;
}
int lineNumber=0;
while(fgets(path,path_MAX,fp)!=NULL){
printf(“命令输出的第%i行:%s\n”,行号++,路径);
}
int returnValue=pcloseHandler(fp);//确保关闭!
printf(“子进程返回%i\n”,返回值);
}

popen()确实在等待。另请参见pclose(),请显示您的代码
popen
不等待,但
pclose
等待。但是你的问题可能会受到问题的影响(询问你试图解决的问题,而不是你的实际问题)。请提供“导致我的程序出错的原因”位的详细信息,以便我们能够更容易地指出解决您实际问题的正确方法(它可能涉及或可能不涉及
popen
)。只需一个细节:
popen()
为您提供一个文件流(
file*
),而不是一个文件描述符(
int
)。如果循环读取通过
popen()
运行的命令的输出,则读取的代码应挂起,直到有更多数据或命令终止(更准确地说,关闭进程正在读取的标准输出)。此时,您将返回指示EOF的读取错误。如果没有您的代码,很难知道您做错了什么。@kaylum我添加了一段代码,我正在使用的代码似乎与此不符。我正在写入sysfs文件以加载一些配置。当我从命令提示符下执行此操作时,sysf需要几秒钟的时间但是当我在程序中这样做时,程序会立即完成。这让我觉得程序在正确加载配置之前正在继续。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_WIN32)
    #include <Windows.h>
#else
    #include <unistd.h>
#endif

#ifndef PATH_MAX
    #define PATH_MAX 255 //Usually defined in <Windows.h>
#endif

FILE *popenHandler(const char *args, const char *method)
{
    #if defined(_WIN32)
        return _popen(args, method);
    #else
        return popen(args, method);
    #endif
}

int pcloseHandler(FILE *fp)
{
    #if defined(_WIN32)
        return _pclose(fp);
    #else
        return pclose(fp);
    #endif
}

int main()
{
    FILE *fp; //file pointer to point to command
    char path[PATH_MAX]; //char buffer to store output

#if defined(_WIN32)
    char command[PATH_MAX] = "dir"; //command to execute
#else
    char command[PATH_MAX] = "ls -l"; //command to execute
#endif

    //If you want to include stderr in the results, uncomment the below string
    //strncpy(command, " 2>&1", PATH_MAX); //Merges stderror with stdout

    fp = popenHandler(command, "r"); //function to work on win32 or unix
    if (fp == NULL) {
        printf("ERROR: Failed to execute command %s\n", command);
        return -1;
    }
    int lineNumber = 0;
    while (fgets(path, PATH_MAX, fp) != NULL) {
        printf("Line #%i of output from command: %s\n", lineNumber++, path);
    }
    int returnValue = pcloseHandler(fp); //Make sure to close!
    printf("The sub-process returned %i\n", returnValue);
}