繁体   English   中英

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

[英]system() call or exec() functions not working when i send command with char array in c language

我正在尝试在Linux中制作视频循环器。 为此,我正在使用视频播放器。 我的程序从目录中获取视频和图像列表,然后播放它们。 我的问题是,当我使用字符数组参数从c调用mplayer或图像查看器时,它不起作用。 例如,

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

要么

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

如果我这样打电话的话。 但是当我直接从视频列表中获取并使用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;

        }
    }

我不确定这是唯一的错误,但这显然是您的直接问题:

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

我不知道您是怎么想这会格式化字符串的 它的作用是将liste[counter]复制到command 原因是strcpy的第二个参数是一个带括号的表达式:

("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]);

这将实现您显然期望的结果。 在一个侧面说明,还观察了如何把一个空白的每个逗号使得这整个网上很多更具可读性之后,所以我建议你也这样做。


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

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

  1. 当前正在执行父进程,返回值是子进程的PID
  2. 当前正在执行子进程,返回值为0
  3. 未创建任何进程,返回值为-1

发布的代码无法处理#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. 空值

因为你想执行:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM