【问题标题】:A C program demonstrating how cmd.exe and a linux shell e.g. bash, delimit parameters?一个 C 程序,演示如何 cmd.exe 和一个 linux shell,例如bash,分隔参数?
【发布时间】:2010-11-11 17:27:33
【问题描述】:

我听说 cmd shell 将整个内容传递给命令,然后标准 C 库将其分隔,同时考虑到空格和引号。而在 linux 中,只有 shell 可以做到这一点。

一个带有 while 循环的程序,显示 argsv[i] 显示它是如何被分隔的,但不显示 shell 做了什么,以及 C 库做了什么。

谁能给我指点或给我看一个可以显示它的程序?

【问题讨论】:

  • 为什么你认为你所描述的并没有告诉你shell做什么以及程序必须做什么?
  • 我说的是标准库。我的印象是,一旦进入 main 方法,argsv 就会被库分隔。没有?
  • libc 什么都不做。
  • @Ignacio:在 Windows 上可以。 Windows 上的进程只获取命令行,而不是单个参数。
  • @barlop:Windows 中的进程将命令行作为单个字符串获取。 C 程序在其main 函数中获取一个用于分隔参数的字符串数组。正如您已经注意到的,对于 MS libc,这发生在 stdargv.c

标签: c windows linux command-line cmd


【解决方案1】:

我想你想知道 shell 在 linux 中是如何工作的吧?我认为当我们在命令 shell 上键入任何内容时,shell 会将所有参数作为字符串格式的参数接收,shell 然后 fork+exec 二进制文件并将所有参数作为环境变量传递给新的二进制文件,然后将这些环境变量放入内核新进程的堆栈,稍后进程以 argc 和 argv[] 访问,但 c 库不进行特殊处理。

【讨论】:

  • 谢谢,我很感兴趣,这与它在 Windows 中的完成方式有何不同。理想情况下,这是一个可以证明这一点的程序。
  • 嗨,barlop,堆栈设置(参数设置)是由内核完成的,而不是在应用程序中完成的,因此很难通过程序演示,但是您可以在linux中使用strace来跟踪完整的流程执行,但我不知道如何在 Windows 中完成,我不知道 Windows :-)
  • 在我刚刚下载并尝试了 stracent 的 Windows 系统上(发现谷歌搜索 strace for windows!),我在一个只接受参数并显示它们的程序上尝试了 stracent。但这不是很明显! pastebin.com/gtb7x2L2
  • hmmm.. 好的,那么另一种方法是通过 CRT 进行调试,这是调用主函数的代码(至少在 Linux 中),因此可以使用 -g 编译代码并使用 gdb 来分解并在 __libc_start_main 上中断,后者又调用 main,我希望这有助于了解事情是如何工作的。
【解决方案2】:

在任何 POSIX 或类似 POSIX 的操作系统上,标准库与将命令行解析为组件无关。它完全由外壳完成。 POSIX exec 系列函数采用指针数组,就像 main 接收一样。通常,内核负责将它们干净地排列并保存在跨越exec 的特殊位置(通常是堆栈顶部)(当前一个程序的地址空间被清除时)。

至于 如何 执行 shell 的功能,当您阅读有关 shell 功能的详细说明时,这很简单,尽管很痛苦。你可以在这里找到:

http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html

【讨论】:

    【解决方案3】:

    您认为 Windows cmd.exe 和 Linux shell 工作方式相同的假设是不正确的。尝试在两个系统上执行 echo * - Windows 将显示 *,Linux 将显示当前目录中的文件列表。

    Windows 程序将在argv[1] 中接收*,除此之外什么也没有。 Linux 程序将接收argv 中的许多元素,每个元素都是一个完整的文件名,包括空格(如果有)。

    int main(int argc, char **argv)
    {
        int i;
        for (i = 0;  i < argc;  ++i)
        {
            printf("%d: %s\n", i, argv[i]);
        }
        return 0;
    }
    

    【讨论】:

    • 我在哪里假设 linux shell 和 cmd.exe 工作相同?我知道 * 但这与用空格和引号定义哪个参数是哪个命令的分隔参数无关。无论如何,我正在询问一个程序,该程序演示了它们如何以不同的方式分隔参数。所以不,我不认为它们的工作方式相同。我知道*,它与我的问题无关。如果我的问题是基于任何假设,那就是它们的工作方式不同。
    • @barlop,对不起,如果我误解了这个问题,我认为是标题误导了我。至于shell做了多少,C库做了多少,很难通过程序来演示,因为这一切都是在程序启动之前发生的。
    猜你喜欢
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    相关资源
    最近更新 更多