【问题标题】:Bash internal commands from C program (Ubuntu v/s MacOS)来自 C 程序的 Bash 内部命令(Ubuntu v/s MacOS)
【发布时间】:2019-02-24 09:04:44
【问题描述】:

以下代码成功列出了 Ubuntu bash 和 MacOS bash 上当前目录的内容。

int main() {
    char* args[3];
    args[0] = "ls";
    args[1] = NULL;
    args[2] = NULL;
    execvp(args[0], args);
    return 0;
}

以下代码在 Ubuntu bash 上不打印任何内容,但在 MacOS bash 上打印 ls is /bin/ls

int main() {
    //pid_t pid = fork();
    char * args[3];
    args[0] = "type";
    args[1] = "ls";
    args[2] = NULL;
    //if (!pid) 
    execvp(args[0], args);
    return 0;
}

当我直接在 Ubuntu bash 上运行 type 时,它会打印出 ls is hashed (/bin/ls)

区别在于type 是一个bash 内部命令,而ls 不是。但是为什么 Ubuntu 上的 bash 与 MacOS 上的行为不同呢?

Ubuntu bash 版本:GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

MacOS bash 版本:GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)

纯粹根据版本号判断(这可能是不正确的做法),旧版本可以正确打印输出,而新版本则不能?

【问题讨论】:

  • 你的PATH 是什么?在 MacOSX 上可能有所不同。或者那里的目录不一样。也许 MacOSX 有一些 /usr/bin/type 的东西,但 Ubuntu 没有任何这样的东西

标签: c bash macos ubuntu


【解决方案1】:

您忘记针对execvp 的失败进行测试。至少尝试编码:

if (execvp(args[0], args)) {
   fprintf(stderr, "execvp %s failed: %s\n",
           args[0], strerror(errno));
   exit(EXIT_FAILURE);
} 

可能在您的 Ubuntu 上 execvptype 失败。也许 MacOSX 有一些 /usr/bin/type 或在您的 PATH 中找到的任何内容。

仔细阅读execvp(3)两个 系统上的文档。还可以考虑在 Linux 上使用 strace(1) 来了解发生了什么(MacOSX 可以找到 similar thing)。

请注意,execvp 仅适用于 可执行文件 文件(不适用于 shell 内置命令)

【讨论】:

  • execvp 类型失败:没有这样的文件或目录。你是对的:当我运行 whereis type 时,MacOS 提供 /usr/bin/type,而 Ubuntu 提供 type:
  • 那么有什么方法可以在 Ubuntu 上通过 C 程序执行 type 吗?
  • 你可以运行bash -c 'type %',但这显然是特定于你的shell的。 (所以实际上在 MacOS 上是 /usr/bin/type;它运行 /bin/sh 并执行 builtin type ${1+"$@"}。)
【解决方案2】:

您的问题中没有bash。也就是说,该程序的执行与bash无关。

execvp 实际上是一个系统调用,其效果(如果成功,则不应被视为理所当然)用新的进程映像替换当前执行环境,从指示为的文件加载可执行文件第一个论点。操作系统既不需要也不寻求bash 的帮助来执行程序。

如果你想使用bash,你需要让操作系统运行bash。如果您想运行 bash 内置命令,这可能很有用:

char* args[] = { "bash", "-c", "type ls", 0};
execvp(args[0], args);

但是由于您没有调用bash,因此您依赖于名为type 的外部命令实用程序的存在。正是这种效用的存在与否导致了不同的行为。它与bash 或任何其他shell 无关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多