【问题标题】:How does shell expands *.c?shell如何扩展*.c?
【发布时间】:2016-05-13 12:45:31
【问题描述】:

我在阅读教科书时遇到一个问题 - Unix系统编程

作为第二个参数传递给execvp 的参数数组有多大 当您使用以下命令执行程序 3.5 的execcmd 时 行吗?

execcmd ls -l *.c

答案:答案取决于当前的.c文件的数量 目录,因为 shell 在传递命令之前会扩展 *.c 转至execcmd

计划 3.5:

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "restart.h"
int main(int argc, char *argv[]) {
   pid_t childpid;
   if (argc < 2){     /* check for valid number of command-line arguments */
      fprintf (stderr, "Usage: %s command arg1 arg2 ...\n", argv[0]);
      return 1;
   }
   childpid = fork();
   if (childpid == -1) {
      perror("Failed to fork");
      return 1; 
   }
   if (childpid == 0) {
      execvp(argv[1], &argv[1]);
      perror("Child failed to execvp the command");
      return 1;
   }
   if (childpid != r_wait(NULL)) {
      perror("Parent failed to wait");
      return 1;
   }
   return 0;
}

为什么传递的参数数组的大小取决于当前目录中 .c 文件的数量?是不是参数数组就像

argv[0] = "execcmd";
argv[1] = "ls";
argv[2] = "-l";
argv[3] = "*.c";
argv[4] = NULL;

更新:找到一个很好地解释了 shell 扩展的链接。可能对后来看到这篇文章但不了解 shell 扩展的人有用。 Description about shell expansion

【问题讨论】:

  • 命令shell首先根据当前工作目录的内容扩展*.c。结果文件名列表将替换参数列表中的*.c。然后将扩展的参数列表作为argv 传递给应用程序。它从不将*.c 视为参数。从它的角度来看,它与用户手动键入所有文件名的命令行没有区别。
  • @TomKarzes 谢谢,我现在明白了 :)

标签: c shell unix command-line


【解决方案1】:

不,因为 shell 会进行通配符扩展。 它会在目录中查找与表达式匹配的文件,例如,您可以使用“echo *.c”来发现 shell 将匹配的内容。然后它会列出在 exec 调用中匹配 *.c 的每个文件名,或者如果没有匹配 *.c 则可能会导致有关未找到文件的错误消息。

shell做扩展更强大,相同的文件通配符立即可用于所有程序,如cat、echo、ls、cc。

【讨论】:

  • 所以命令行参数没有作为字符串存储到数组中?
  • 这就是为什么你会发现关于如何防止它变得“好”的问题stackoverflow.com/questions/11456403/…
  • @pm100 哦,好的,我现在明白了。这个链接解释得很好。也许对于不了解外壳扩展的人来说,这是一个很好的参考。 link
  • 好吧,USP 称其为“外壳扩展”,因为它是外壳做的。罗宾的书很好地解释了很多东西。
猜你喜欢
  • 2012-02-07
  • 1970-01-01
  • 2011-01-12
  • 2017-06-01
  • 1970-01-01
  • 2012-01-08
  • 2020-12-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多