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

时间:2015-11-14 20:26:49

标签: c execvp strsep

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

1 个答案:

答案 0 :(得分:3)

如果缓冲区中有可用空间,

fgets()会读取换行符。因此,当您输入ls时,它实际上是ls\n。很明显,execvp()无法找到这样的命令而且失败了。所以解决方法是删除尾随换行符(如果有的话)。

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

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