【问题标题】:GetCommandLine linux *true* equivalentGetCommandLine linux *true* 等效
【发布时间】:2012-12-12 03:06:36
【问题描述】:

与 Linux 等效的 GetCommandLine 和 CommandLineToArgv 类似的问题

是否可以在 linux 中获取 raw 命令行?文件 /proc/self/cmdline 被销毁。

./a.out files="file 1","file 2" param="2"

打印

./a.outfiles=file 1,file 2param=2

这是垃圾

转义命令行确实适用于除第一个以外的所有参数。

./a.out files=\"fil 1\",\"fil 2\"\ param=\"2\"

打印

./a.outfiles="fil1","fil2" param="2"

【问题讨论】:

  • 如何在参数之间输出一个空格
  • 似乎参数用 0 字节分隔并删除了引号。 cat /proc/self/cmdline | tr '\000' ' ' 返回cat /proc/self/cmdline
  • 并且/proc/self/cmdline 不包含“原始”命令行;它包含与argv 完全相同的信息。
  • 这是 Windows 和 UNIX 之间的根本区别之一。这两种方法从根本上来说都没有对错,它们都有不同的优点和缺点。

标签: c++ c linux windows equivalent


【解决方案1】:

你不能那样做。命令行参数实际上作为单独的字符串传递给新进程。查看linux内核源码: kernel_execve

请注意,kernel_execve(...) 采用 const char *argv[] - 因此在 Linux 中没有长字符串命令行之类的东西 - 它是上面的层,需要将参数拆分为单独的组件。

编辑:实际上,系统调用在这里:

excve system call

但上面的说法仍然适用。 argv 的参数在内核从 C 库调用 exec 中获取它时已经被拆分。

生成 argv[] 数组是“程序启动器”(通常是 shell,但不是必须的)的责任。它将执行“通配符”(将通配符文件名扩展为匹配的实际文件)并去除引号、变量替换等。

我还要指出,尽管 C 库中有多种“exec”变体,但进入内核的方式只有一种。所有变体最终都出现在我上面链接的execve 系统调用中。其他变体仅仅是因为调用者可能不喜欢将参数拆分为单个元素,因此 C 库通过为程序员这样做来“帮助”。类似地,将环境数组传递给新程序 - 如果程序员不需要特定环境,他/她可以调用自动获取父进程 env 的变体。

【讨论】:

  • 具体来说,所有的引用和通配符都由 shell 处理。只有当外壳将原始文件存储在孩子可以访问的地方时,您才能访问它。这将是特定于 shell 的。
  • 垫子,我建议将@BenVoigt 的评论中的信息添加到您的答案中(尽管 shell 以外的程序也可以调用程序,并且可能以不同的方式构建 argv)。
  • @Keith:父进程不必是外壳,是的。但是根本没有任何命令行可以讨论,只有exec 的一组参数。相关:system() 调用 shell 进行命令行处理。
  • @BenVoigt:在 shell 中有一个命令行;关键是它对被调用的进程不可见。
  • 更新了一点。我只是希望这是值得的努力...... :)
猜你喜欢
  • 1970-01-01
  • 2012-08-09
  • 2018-05-20
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 2011-12-26
  • 2012-07-17
  • 1970-01-01
相关资源
最近更新 更多