What does execvp actually do? [duplicate]

2019-07-28 01:40发布

问题:

Possible Duplicate:
Writing a shell - how to execute commands

I've been tasked with writing a shell in C. So far I understand that execvp will try to run the program in arg1 with arg2 as parameters. Now it seems that doing this

execvp ("ls", args); //assume args is {"ls", ">", "awd.txt"}

is not equivalent to typing this in the console

ls > awd.txt

I realize that I need to use freopen to achieve the same results but I'm curious what execvp is doing.

回答1:

The exec family of functions are ultimately a system call. System calls go straight into the kernel and typically perform a very specific service that only the kernel can do.

Redirection, on the other hand, is a shell feature.

So, when one types ls > awd.txt at a shell, the shell first does a fork(2), then it closes standard output in the child, then it opens awd.txt on file descriptor one so that it's the new standard output.

Then, and only then, the shell will make an exec-family system call.

In your case you simply passed the strings > and awd.txt to the exec system call, and from there to ls. BTW, be sure you terminate your execvp arg array with a null pointer.


Note: As you can see, the redirection operators are never seen by the executed program. Before Unix, directing output to a file had to be done by every program based on an option. More trivia: most programs never know they were redirected, but ironically, ls does check to see if its output is a tty, and if so, it does the multi-column formatted output thing.



回答2:

It's executing ls with 2 arguments: > and awd.txt. It is equivalent to running:

'ls' '>' 'awd.txt'


回答3:

You can pass your command directly to the shell:

char * const args[] = { "sh", "-c", "ls > awd.txt", NULL};
execvp("/bin/sh", args);

But it doesn't seems like a good idea.