Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
拆分Unix命令以与exec一起使用_C_Unix_Exec_Ansi - Fatal编程技术网

拆分Unix命令以与exec一起使用

拆分Unix命令以与exec一起使用,c,unix,exec,ansi,C,Unix,Exec,Ansi,我有一个程序,它从输入中获取命令,然后使用execl执行它。它必须是execvp家族的函数。现在,假设输入行在中,我可以简单地使用execlallBeforeFirstSpaceFromIn,in,或者我必须分成更小的字符串吗?如果是这样,我可以简单地将所有空格更改为\0吗?是的,您需要将参数作为单独的字符串传递 对于execlX函数,需要将每个参数作为参数传递: execl(prog, arg1, arg2,...); 对于execvX函数,您需要传递一个c样式字符串数组: char **a

我有一个程序,它从输入中获取命令,然后使用execl执行它。它必须是execvp家族的函数。现在,假设输入行在中,我可以简单地使用execlallBeforeFirstSpaceFromIn,in,或者我必须分成更小的字符串吗?如果是这样,我可以简单地将所有空格更改为\0吗?

是的,您需要将参数作为单独的字符串传递

对于execlX函数,需要将每个参数作为参数传递:

execl(prog, arg1, arg2,...);
对于execvX函数,您需要传递一个c样式字符串数组:

char **argv = /* ... */;
argv[0] = "arg1";
argv[1] = "arg2";
execv(prog, args);
要拆分输入字符串,您可以使用strtok,或者只需执行以下操作:

char **argv = /* malloc stuff */;
char *prev = in;
cnt = 0;
while (in[0]) {
  if (in[0] == ' ') {
    in[0] = 0;
    argv[cnt++] = prev;
    prev = in + 1;
  }
  in++;
}
argv[cnt++] = prev;
argv[cnt]   = NULL;
"/bin/cat file1 file2"

是的,您需要将参数作为单独的字符串传递

对于execlX函数,需要将每个参数作为参数传递:

execl(prog, arg1, arg2,...);
对于execvX函数,您需要传递一个c样式字符串数组:

char **argv = /* ... */;
argv[0] = "arg1";
argv[1] = "arg2";
execv(prog, args);
要拆分输入字符串,您可以使用strtok,或者只需执行以下操作:

char **argv = /* malloc stuff */;
char *prev = in;
cnt = 0;
while (in[0]) {
  if (in[0] == ' ') {
    in[0] = 0;
    argv[cnt++] = prev;
    prev = in + 1;
  }
  in++;
}
argv[cnt++] = prev;
argv[cnt]   = NULL;
"/bin/cat file1 file2"

因此,您的输入是单个字符串,类似于:

char **argv = /* malloc stuff */;
char *prev = in;
cnt = 0;
while (in[0]) {
  if (in[0] == ' ') {
    in[0] = 0;
    argv[cnt++] = prev;
    prev = in + 1;
  }
  in++;
}
argv[cnt++] = prev;
argv[cnt]   = NULL;
"/bin/cat file1 file2"
不,不能将/bin/cat作为一个参数传递给execl,而将file1 file2作为另一个参数传递给execl。这将导致/bin/cat尝试打开名为file1 file2的文件。您希望它打开两个文件,file1和file2,这意味着您需要传递三个单独的参数

execl可能不适合你所做的。这是一个变量函数;要调用它,您必须知道在编写代码时要向其传递多少个参数。因此:

execl("/bin/cat", "file1", "file2");
应该可以,但不能从字符串生成调用

您希望改用execv*函数之一。例如:

int execv(const char *path, char *const argv[]);
argv参数是指向char的指针,它应该指向char*元素数组的第一个元素,每个元素都指向以“\0”结尾的字符串的第一个字符

因此,您必须构建指针数组,并对每个指针进行初始化,以指向一个字符串参数

现在,如果您有一个包含字符串的数组:

"/bin/cat file1 file2"
一种方法是用空字符替换空格:

"/bin/cat\0file1\0file2\0"
最后一个\0已经存在。然后,您可以构造char*数组,使每个元素都指向数组的开头,或者正好位于刚刚创建的一个“\0”字符之后。每个这样的指针都是指向字符串的有效指针

但我不一定推荐这种方法。如果您的输入字符串恰好包含多个单词之间的空格,而您可能希望将这些空格视为单个空格,或者如果您希望执行一些类似于扩展通配符的操作,那么您将遇到问题。我建议您自己分配阵列并将适当的数据复制到其中。重复使用输入字符串所节省的空间不值得付出努力

当然,最简单的方法是:

char command[] = "/bin/cat file1 file2";
system(command);
exit(0);

它将命令字符串传递给/bin/sh,这将为您完成所有工作。但是你不会学习如何使用exec*函数,我想这是本练习的重点。

因此你的输入是一个字符串,类似于:

char **argv = /* malloc stuff */;
char *prev = in;
cnt = 0;
while (in[0]) {
  if (in[0] == ' ') {
    in[0] = 0;
    argv[cnt++] = prev;
    prev = in + 1;
  }
  in++;
}
argv[cnt++] = prev;
argv[cnt]   = NULL;
"/bin/cat file1 file2"
不,不能将/bin/cat作为一个参数传递给execl,而将file1 file2作为另一个参数传递给execl。这将导致/bin/cat尝试打开名为file1 file2的文件。您希望它打开两个文件,file1和file2,这意味着您需要传递三个单独的参数

execl可能不适合你所做的。这是一个变量函数;要调用它,您必须知道在编写代码时要向其传递多少个参数。因此:

execl("/bin/cat", "file1", "file2");
应该可以,但不能从字符串生成调用

您希望改用execv*函数之一。例如:

int execv(const char *path, char *const argv[]);
argv参数是指向char的指针,它应该指向char*元素数组的第一个元素,每个元素都指向以“\0”结尾的字符串的第一个字符

因此,您必须构建指针数组,并对每个指针进行初始化,以指向一个字符串参数

现在,如果您有一个包含字符串的数组:

"/bin/cat file1 file2"
一种方法是用空字符替换空格:

"/bin/cat\0file1\0file2\0"
最后一个\0已经存在。然后,您可以构造char*数组,使每个元素都指向数组的开头,或者正好位于刚刚创建的一个“\0”字符之后。每个这样的指针都是指向字符串的有效指针

但我不一定推荐这种方法。如果您的输入字符串恰好包含多个单词之间的空格,而您可能希望将这些空格视为单个空格,或者如果您希望执行一些类似于扩展通配符的操作,那么您将遇到问题。我建议您自己分配阵列并将适当的数据复制到其中。重复使用输入字符串所节省的空间不值得付出努力

当然,最简单的方法是:

char command[] = "/bin/cat file1 file2";
system(command);
exit(0);
它将命令字符串传递给/bin/sh,这将为您完成所有工作。但是这样你就不会学习如何使用exec*函数了
我想这是本练习的重点。

调用exec基本上有两种方法,一种是逐个提供所有参数execl,另一种是提供参数数组execv

如果提供一个长字符串,其中所有参数都用\0分隔,exec将无法理解在第一个参数之后还有其他参数

所以你要么

使用execl并提供参数列表,例如…、in、in+x、in+y、NULL 或者创建一个char*字符串数组,每个元素都指向in、in+x、in+y,…,并使用execv 用x和y。。。作为参数长字符串中的索引,例如

x是8,y是13。你可以创建一个字符串数组

char *args[] = { in, in+x, in+y, NULL };

然后使用execv execvin,args

调用exec基本上有两种方法,一种是逐个提供所有参数execl,另一种是提供参数数组execv

如果提供一个长字符串,其中所有参数都用\0分隔,exec将无法理解在第一个参数之后还有其他参数

所以你要么

使用execl并提供参数列表,例如…、in、in+x、in+y、NULL 或者创建一个char*字符串数组,每个元素都指向in、in+x、in+y,…,并使用execv 用x和y。。。作为参数长字符串中的索引,例如

x是8,y是13。你可以创建一个字符串数组

char *args[] = { in, in+x, in+y, NULL };

然后使用execv execvin,args

NULL是一个NULL指针常量。您可能是指空字符“\0”。是的,很抱歉:如果您已经阅读了我的答案,请再次阅读;在过去的几分钟里我已经更新了好几次。NULL是一个NULL指针常量。您可能是指空字符“\0”。是的,很抱歉:如果您已经阅读了我的答案,请再次阅读;在过去的几分钟里,我已经对它进行了多次更新。如果该命令包含,比如/bin/echo Hello World,该怎么办?它将被拆分为/bin/echo、Hello和World。@DavidCzihak:是的,它会-这是否正确取决于您的要求。shell通常不只是在空白处拆分命令行;echo hello world向echo命令传递一个参数hello world,该参数包括空格,但不包括引号。但我认为这比OP目前试图解决的问题还多。也许吧,但我认为无论多么明显,都应该指出可能存在的陷阱。如果命令包含,比如/bin/echo Hello World,该怎么办?它将被拆分为/bin/echo、Hello和World。@DavidCzihak:是的,它会-这是否正确取决于您的要求。shell通常不只是在空白处拆分命令行;echo hello world向echo命令传递一个参数hello world,该参数包括空格,但不包括引号。但我认为这比OP目前试图解决的问题还多。也许吧,但我认为无论多么明显,都应该指出可能存在的陷阱。事实上,所有参数都以\0分隔的长字符串不是字符串,根据定义,它以第一个“\0”字符结尾。例如,任何需要指向字符串的指针的函数,如果将其传递给echo\0hello\0world,则只会看到echo。这基本上就是您所说的。事实上,所有参数都用\0分隔的长字符串不是字符串,根据定义,它以第一个“\0”字符结尾。例如,任何需要指向字符串的指针的函数,如果将其传递给echo\0hello\0world,则只会看到echo。基本上就是你说的。