【问题标题】:Execlp with echo and md5sum使用 echo 和 md5sum 执行
【发布时间】:2017-02-24 12:16:34
【问题描述】:

我正在尝试使用execlp() 编写一个程序,以将字符串的 md5sum 的输出保存到标准输出。基本上,模拟这个:

echo "Hello!" | md5sum

得到这个输出:

31ebdfce8b77ac49d7f5506dd1495830  -

这是我首先尝试解决的问题:

char string[] = "Hello!";
execlp("md5sum", "md5sum", string, NULL); 

虽然,以这种方式使用execlp() 期望参数是文件,而不是字符串。所以我尝试了这个:

char string[] = "Hello!";
execlp("echo", "echo", string, "md5sum", NULL);

不过,这会生成Hello! md5sum 的输出。它将"md5sum" 识别为字符串,而不是系统调用。

怎样才能让echo和md5sum协同工作?或者我该怎么做才能使 md5sum 在字符串而不是文件上工作?也许我应该使用与execlp() 不同的功能?

【问题讨论】:

  • 你需要 pipe、fork 和 execlp 来完成这项工作。
  • md5sum 不带字符串,它带文件。
  • md5sum 显然可以从stdin 读取。接受@JonathanLeffler 的建议
  • 在 shell 中,stdinmd5sumstdoutecho。正如第一条评论所暗示的那样,您需要模仿它。
  • 在 unix 编程中,fork 和执行一个进程,通过一个管道给它一个字符串并通过另一个管道收集输出,这是一个很酷的练习,每个 unix 程序员都应该编写一次代码,因为它会帮助您理解一些重要的概念。但是对于正常使用,使用库函数更快,通常更容易。 Wikipedia 可能会帮助您找到一个。 (对于加密,只使用信誉良好的库,并确保您进行单元测试;将您的输出与命令行实用程序进行比较也很好。

标签: c bash md5sum


【解决方案1】:

在我回答你的问题之前,有一些顾虑。

而且 MD5 已经很久很久很久没有破解了。使用给定的 MD5 和创建文件相当简单。 SHA1 即将推出。使用SHA-256 或更好。没关系,如果您的应用程序与安全无关,您和我都没有资格就攻击面做出决定,不要冒险。

您是否考虑过在 C 中进行校验和?它将更快、更便携、更可靠。有any number of checksum libraries。 Gnome Lib provides checksums,等等。

#include <stdio.h>
#include <glib.h>

int main() {
    char string[] = "Hello!";

    printf("checksum for %s is %s\n",
           string,
           g_compute_checksum_for_string(G_CHECKSUM_SHA256, string, -1)
    );
}

好的,继续这个问题。


第一个问题是md5sum 不接受字符串,而是接受文件。这与execlp 无关,md5sum 程序就是这样工作的。您可以从标准输入读取 md5sum,但这涉及管道,而且我想承担更多。我提到要使用图书馆吗?

这会导致您的第二个问题:错误检查。我没有看到。对 exec 的任何错误检查都会在 exec 之后立即进行;如果成功则调用程序将立即退出。

那么问题是execlp 可能是矫枉过正,除非您更改正在运行的程序的名称。使用execvp。我更喜欢它,因为它将程序的所有参数放在一个很好的列表中,以后可以用于错误检查。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

int main() {
    char *args[] = { "md5um", "Hello!", NULL };

    int exit_status = execvp(args[0], args);

    fprintf(stderr, "executing %s ", args[0]);
    for( int i = 1; args[i] != NULL; i++ ) {
        fprintf(stderr, "%s ", args[i]);
    }
    fprintf(stderr, "exited with %d: %s\n", exit_status, strerror(errno));
}

【讨论】:

    猜你喜欢
    • 2013-07-14
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 2011-08-07
    • 2013-11-15
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    相关资源
    最近更新 更多