简体   繁体   中英

execvp command not running ls -l *.c

My execvp is not running ls -l *.c command. I have tried to use two methods:

  1. One with the file path where my ls is located which is in \bin\ls .
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    char *cmdargs[] = { "ls", "-l", "*.c", NULL };
    pid_t pid;
    pid = fork();
    if (pid == 0)
        execvp("\bin\ls", cmdargs);
    else
    {
        wait(NULL);
        printf("Child terminates\n");
    }
    return 0;
}

Output:

ls: *.c: No such file or directory
Child terminates
  1. The second method I used was to add cmdargs[0] instead of the file path.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    char *cmdargs[] = { "ls", "-l", "*.c", NULL };
    pid_t pid;
    pid = fork();
    if (pid == 0)
        execvp(cmdargs[0], cmdargs);
    else
    {
        wait(NULL);
        printf("Child terminates\n");
    }
    return 0;
}

Output:

ls: *.c: No such file or directory
Child terminates

When I just run the command ls -l *.c , it does show me all the files which end with .c . Execvp does not show me the files. There was a question related to this but that did not help me.

GLOB pattern is expanded by shell, not the ls itself. You may achieve what you want by creating a subshell via exec. Here's an example of that:

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

int main() {
    char *cmdargs[] = { "sh", "-c", "ls -l *.c", NULL };

    pid_t pid;
    pid = fork();
    if (pid == 0) {
        execvp(cmdargs[0], cmdargs);
    } else {
        wait(NULL);
        printf("Child terminates\n");
    }

    return 0;
}

You may also employ system(3) for this if you want.

The asterisk pattern * is carried on by the shell, but by the ls .

You can use exec with sh , for example.

Editing over the OP's response, Obtain all files without using *.c in a string array and filter the strings as you wish.

When you enter ls -l *.c , the shell will parse that command, find the glob pattern and expand it. It will then call ls with the expanded argument list, calling execvp with an array like {"ls", "-l", "ac", "bc", "cc", NULL} . Neither ls nor the execvp expand globs by themselves, it's the shell that does it.

So if you want to use globs, your options are to either expand them yourself (either by manually going through the current directory and adding all files that end with .c to your array or by using the POSIX glob function), or to go through the shell. You can do the latter either by explicitly invoking by using {"sh", "-c", "ls -l *.c", NULL} as the array you pass to execvp (or similarly, but without the array, using execl etc.) or you could use system("ls -l *.c") , which always goes through the shell.

Note that you definitely don't want to go through the shell if the arguments contain untrusted user input, so in that case expanding the glob(s) yourself / using glob would be the way to go.

Alternatively to invoking the shell to expand the *.c glob pattern to files, you can use glob to expand *.c to list of files yourself and then construct a dynamically allocated array of arguments.

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

int main() {
    glob_t result = {0};
    int err = glob("*.c", GLOB_ERR, NULL, &result);
    if (err) return err;
    char **cmdargs = malloc((2 + result.gl_pathc + 1) * sizeof(cmdargs));
    if (cmdargs == NULL) return EXIT_FAILURE;
    cmdargs[0] = "ls";
    cmdargs[1] = "-l";
    for (size_t i = 0; i < result.gl_pathc; ++i) {
        cmdargs[i + 2] = result.gl_pathv[i];
    }
    cmdargs[2 + result.gl_pathc] = NULL;

    pid_t pid = fork();
    if (pid == 0) {
        execvp(cmdargs[0], cmdargs);
    } else {
        wait(NULL);
        printf("Child terminates\n");
    }
    globfree(&result);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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