1

我的任务是编写一个简单的 linux shell。我正在使用外部命令。我们需要使用 execv。

for (int i = 0; i < count; i++){
  char path[1024];
  strcpy(path, PATHS[i]);         // PATHS is an array of cstrings, the paths in $PATH
  strcat(path, "/");
  strcat(path, command[0]);       // command and commands are essentially the same
  printf("%d %s",i,path);         // they are essentially argv[]
  if (!execv(path, commands))     // for ls -l $HOME
    break;                        // commands[0] = ls [1] = -l [2] = my home dir

现在我只用 ls 测试它。ls 运行完全正常,但程序在 execv 成功后立即关闭。有什么办法让我继续使用 execv 来检查正确的路径并让程序在 execv 成功后继续运行?

4

2 回答 2

5

exec 系列函数不会杀死您的进程。它们现有的过程映像替换为您执行的过程映像。

基本上,它的工作方式好像该进程(及其 PID 和相关的内核资源)保持不变,只是旧映像中的所有代码都被删除并替换为程序中的代码,然后加载到内存中并像初始化一样这完全是一个新的过程。PID不会改变,所以如果你想创建一个有自己PID的子进程,你必须使用另一个函数。

正确的处理方法是先分叉,然后从子进程中使用 exec*。这样,您可以使用父实例中的等待函数来等待子实例终止并收回控制权。

+--------------+             +--------------+                             +----------------------+
|Parent process|+---fork()-->|Parent process|+---------wait()------------>|Parent process resumes|
+--------------+      +      +--------------+                             +----------------------+
                      |                                                               +
                      |                                                               |
                      |                                                               |
                      |      +-------------+              +-----------------+         |
                      +----->|Child process|+--execv()--->|New process image|+--exit--+
                             +-------------+              +-----------------+
于 2014-01-30T09:16:26.593 回答
2

各种形式的 exec() 实际上当前进程映像替换为请求的进程映像。它们不会产生新的进程。所以你需要自己做,使用 fork()。

于 2014-01-30T09:16:34.143 回答