Hi I'm trying to use execv
function in forked child process to execute the commands like: ls
, grep
, sort
, awk
and so on in terminal.
However, ls
, grep
works but sort
, awk
and other things are not working and execv
returns -1
for failure.
Inputs for argv
was "sort t.txt"
by stdin
and argv[0]=sort
, argv[1]=t.txt
. When I put in grep 5 t.txt
for example, it printed out 3 numbers in t.txt that includes 5 and ls
printed out every file in directory. Why do only ls
and grep
work and rest of commands don't?
char* command(char** argv) {
char* ptr = malloc(200);
if (!strcmp(argv[0], "ls") || !strcmp(argv[0], "man") || !strcmp(argv[0], "grep")
|| !strcmp(argv[0], "sort") || !strcmp(argv[0], "awk") || !strcmp(argv[0], "bc")) {
sprintf(ptr, "/bin/%s", argv[0]);
}
return ptr;
}
//inside fork=
char* pos = command(argv);
if (execv(pos, argv) < 0) {
printf("%s\n", argv[0]);
if(argv[1]!=NULL)
printf("%s\n", argv[1]);
if(argv[2]!=NULL)
printf("%s\n", argv[2]);
perror("execv");
fprintf(stderr, "%s: Command not found.\n", argv[0]);
free(pos);
exit(0);
}
free(pos);
mini> sort t
sort
t
execv: No such file or directory
sort: Command not found.
mini> ls
Makefile minishell.c pa2 t
mini>
CodePudding user response:
The problem is because you hard-code the commands to be found in /bin/
, and some commands (like the sort
command) isn't in that location (sort
is typically in /usr/bin/
).
To solve that problem, and to be able to use any command in the standard path, use execvp
instead:
execvp(argv[0], argv);
The difference from execv
is that execvp
will use the environment variable PATH
to search for the command.
Please read the exec
family manual page for details about the different versions.