1

出于某种原因,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
4

1 回答 1

3

fgets()如果缓冲区中有可用空间,则读取换行符。所以当你输入时ls,它实际上是ls\n. 显然,execvp()找不到这样的命令并且它失败了。所以解决方案是删除尾随换行符,如果有的话。

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

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

于 2015-11-14T20:41:45.327 回答