当我使用c语言的char数组发送命令时,system()调用或exec()函数不起作用

时间:2017-07-16 12:09:23

标签: c linux

我正在尝试在linux中制作视频looper。为此,我使用mplayer视频。我的程序从目录中获取视频和图像列表并播放它们。我的问题是当我用c数组参数从c调用mplayer或图像查看器时它无法正常工作。 例如,

system("eog -f /home/user/Desktop/Video/screenshot_0000.png");

system("mplayer -fs /home/user/Desktop/Video/video1.mov");

如果我这样打电话就行了。但是当我从directy获取视频列表并使用char数组发送它时它无法正常工作。当我尝试system()调用它给出'sh:1:video1.mov not found'错误,当我使用exec()函数时没有任何反应。

这是我的代码;

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <dirent.h>
    #include <string.h>

    #define FILE_PATH "/home/user/Desktop/Video/"

    char *getExt (const char *fspec) {
        char *e = strrchr (fspec, '.');
        if (e == NULL)
            e = ""; // fast method, could also use &(fspec[strlen(fspec)]).
        return e;
    }

    void get_list(char liste[][150])
    {
        DIR *d;
        struct dirent *dir;
        char *path = ("%s.",FILE_PATH);
        d = opendir(path);
        int counter=0;
        /*if(d != NULL)
        {
            while((dir=readdir(d))!= NULL)
            {
    //          printf("%s\n", dir->d_name);
                if(dir->d_type==DT_REG)
                    file_numbers++;
            }
            closedir(d);

        }
        char liste[file_numbers][150];*/
        d = opendir(path);
        if(d != NULL)
        {
            while((dir=readdir(d))!= NULL)
            {
    //          printf("%s\n", dir->d_name);
                if(dir->d_type==DT_REG)
                {   
                    strncpy(liste[counter],dir->d_name,150);
    //              printf("%s\n", liste[counter]);
                    counter++;
                }
            }
            closedir(d);

        }

    }

    int main ()
    {
        int status;
        pid_t child_pid, pid_w;
        DIR *d;
        struct dirent *dir;
        char *path = ("%s.",FILE_PATH);
        d = opendir(path);
        int file_numbers=0;
        int counter = 0;
        if(d != NULL)
        {
            while((dir=readdir(d))!= NULL)
            {
    //          printf("%s\n", dir->d_name);
                if(dir->d_type==DT_REG)
                    file_numbers++;
            }
            closedir(d);

        }
        char liste[file_numbers][150];
        get_list(liste);
        /*for(int i = 0; i< file_numbers;i++)
            printf("%s\n", liste[i]);*/

        while(1)
        {
            char *ext = getExt(liste[counter]); 
            //printf("eog -f %s/%s\n",PATH,liste[counter]);
            child_pid = fork();
            if(child_pid==0)
            {
                //printf("-eog -f %s/%s\n",PATH,liste[counter]);
                if(!strcmp(ext,".JPG") || !strcmp(ext,".jpg") || !strcmp(ext, ".gif") || !strcmp(ext,".png") || !strcmp(ext, ".PNG") || !strcmp(ext, ".GIF"))
                {   
                    //printf("eog -f %s%s\n",FILE_PATH,liste[counter]);
                    char command[1000];
                    strcpy(command,("eog -f %s%s",FILE_PATH,liste[counter]));
                    //printf("%s", command);
                    execl(command,command,NULL,NULL);
                    sleep(5);
                }           
                else if (!strcmp(ext,".mov") || !strcmp(ext, ".mp4") || !strcmp(ext, ".avi") || !strcmp(ext,".wmv"))
                {
                    //printf("mplayer -fs %s%s\n",FILE_PATH,liste[counter]);
                    char command[1000];
                    strcpy(command,("mplayer -fs %s%s",FILE_PATH,liste[counter]));
                    //printf("%s",command);
                    execl(command,command,NULL,NULL);
//                  system(command);

                }
                else 
                    printf("--%s%s",FILE_PATH,liste[counter]);      
            }
            else
            {
                pid_w = waitpid(child_pid,&status,0);
    //          system("eog -f /home/user/Desktop/Video/screenshot_0000.png");
    //                  sleep(5);
    //                  exit(EXIT_SUCCESS);
            }
            counter++;
            if(counter >=file_numbers)
                counter =0;

        }
    }

2 个答案:

答案 0 :(得分:2)

我不确定这是唯一的错误,但这显然是你眼前的问题:

strcpy(command,("mplayer -fs %s%s",FILE_PATH,liste[counter]));

我不知道你是怎么想到这会以某种方式格式化一个字符串。它的作用是将liste[counter]复制到command。原因是你的strcpy的第二个参数是一个带有paranthesized的表达式:

("mplayer -fs %s%s",FILE_PATH,liste[counter])

它使用逗号运算符,)两次。逗号运算符执行以下操作:

1。)它评估逗号顺序的两侧(首先是左侧,然后是右侧)  2.)其评估结果是右侧,其他结果只是丢弃(*)

所以,这里

"mplayer -fs %s%s",FILE_PATH,liste[counter]

完全等同于

liste[counter]

您要找的是snprintf()

snprintf(command, sizeof(command), "mplayer -fs %s%s", FILE_PATH, liste[counter]);

这将做你明显的期望。另外,还要观察每个逗号后面的空格是如何让整行更多更具可读性,所以我建议你也这样做。

(*)但副作用的顺序是明确定义的,这就是它的用途 - 当然,这里你没有任何副作用

答案 1 :(得分:0)

fork()的调用可能会导致三种不同的返回状态。

  1. 当前正在执行父进程,返回的值是子进程的PID
  2. 当前正在执行子进程,返回值为0
  3. 未创建任何进程,返回值为-1
  4. 发布的代码未能处理#3。

    推荐:

     child_pid = fork();
     switch( child_pid )
     {
         case 0:  // child
             ....
         break;
    
         case -1: // error
             perror( "fork failed" );
             exit( EXIT_FAILURE );
             break;
    
         default:  // parent
             pid_w = waitpid(child_pid,&status,0); 
             break;
     } // end switch()
    

    execl()的调用需要以下参数:

    1. const char *可执行文件的路径
    2. const char *第一个可执行参数
    3. const char *第二个可执行参数
    4. ....
    5. NULL
    6. 因为你想执行:`

      eog -f %s%s",FILE_PATH,liste[counter]));
      

      execl()的调用应类似于:

      char buffer[1024];
      sprintf( "%s%s", FILE_PATH, liste[counter] );
      execl( "eog", "eog", "-f", buffer, NULL );
      // the 'execl()' function does not return 
      // unless there was an error so:
      perror( "execl failed" );
      exit( EXIT_FAILURE );      // this exits child process when failure occurred