execvp(): 没有这样的文件或目录?

execvp(): no such file or directory?

出于某种原因,execvp() 在我的 PATH 文件(包括 /bin)中找不到命令(如 ls、pwd 等)。因为我有一个带有 ls 的自定义终端别名,我正在使用 pwd 等来测试(以及一台新的 Linux 机器),但我一直在输出:

gcc main.c
./a.out

What would you like to do?
ls
arg[0]: ls

arg[1]: (null)
arg[2]: (null)
arg[3]: (null)
arg[4]: (null)
arg[5]: (null)
arg[6]: (null)
arg[7]: (null)
arg[8]: (null)
arg[9]: (null)
before exec
after exec
ERROR: No such file or directory

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

/* 
Write a c program that runs a command line program with exactly one command line argument. It should work as follows:
Prompts the user for a program to run via the command line.
Reads in that line (using fgets) and parses it to be used by one of the exec functions.
Runs the command using exec
You do not need to fork off a separate process and wait, the purpose of this assignment is only to parse a single line of input and run a program once.
*/

int main() {
  printf("\nWhat would you like to do?\n");

  char* input = malloc( 100 ); //100 character string for input
  fgets(input, 100, stdin); //reads from stdin (terminal input "file")

  //parses command in input (max of 8 flags)
  int number_of_args = 10;

  char *args[number_of_args];

  //puts cmd && flags in args
  int i = 0;
  for(; i < number_of_args; i++) {
    args[i] = strsep( &input, " ");
    printf("arg[%i]: %s\n", i, args[i]);
  }
  args[number_of_args - 1] = 0; //last element for execvp must be NULL;
  //  printf("nullify final index -> args[%i] = %s\n", number_of_args - 1, args[number_of_args -1]);

  printf("before exec\n");
  int e = execvp( args[0], args);
  printf("after exec\n");
  if(e < 0)
    printf("ERROR: %s\n", strerror(errno));

  return 0;
}

编辑:我认为最好也包含我的 PATH:

echo $PATH
/usr/local/bin:/usr/local/bin:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
如果缓冲区中有 space 可用,

fgets() 会读入换行符。所以当你输入ls时,它实际上是ls\n。显然,execvp() 找不到这样的命令,它失败了。所以解决方案是删除尾随的换行符,如果有的话。

char *p = strchr(input, '\n');
if (p)  *p = 0;

您还应该使用 argc 进行参数处理(如果您通过 main() 的参数读取命令和参数)而不是假设一些固定数字。或者在第一次 strsep() returns NULL 时简单地中断循环。从技术上讲,当您打印所有这些空字符串时,您的代码会调用 未定义的行为