【问题标题】:Bash script in C language for android ndk用于 android ndk 的 C 语言 Bash 脚本
【发布时间】:2020-12-30 03:23:15
【问题描述】:

我对此有疑问: C代码

#define CREATE_HTML_FILE_SCRIPT "/bin/curl https://coinmarketcap.com/it/currencies/bytecoin-bcn/ > /data/data/com.example.bytecoin/bcn.html"

#define CREATE_TEMP_FILE_SCRIPT "/data/local/lynx /data/data/com.example.bytecoin/bcn.html -dump > /data/data/com.example.bytecoin/bcn.txt"

system(CREATE_HTML_FILE_SCRIPT);
system(CREATE_TEMP_FILE_SCRIPT);

如果我从 adb shell 运行这些命令都运行良好,但是当从应用程序执行这些命令时,file.html 和 file.txt 为空...我不明白为什么以及如何解决它。

【问题讨论】:

  • 我认为可能会发生两件事之一。一是您可能有权限问题,您尝试将这些文件写入设备存储。二是,也许您需要指定读取和写入的完整路径。此外,由于您正在执行 Linux 命令行参数。也许还可以指定 curl 和 lynx 的可执行文件的位置。如/usr/bin/curl link > /my/directory/file.html 等。
  • 为什么没有找到一种方法来获取 stdout/stderr 并检查错误?
  • @Lkabo 我尝试为 curl 和 lynx 指定可执行文件的位置,但我得到了相同的行为......
  • @Lkabo 我的手机有root权限,所以我拥有所有权限,对吗?当我使用 adb shell 执行这两个字符串时,它们可以正常工作,但是在应用程序中它们会创建空文件。
  • 我想知道应用程序是否正在以 root 访问权限执行命令?

标签: android c android-ndk


【解决方案1】:

嗯,lynx 是一个交互式程序,所以我认为在 system() 调用中使用它时会遇到麻烦。但不是curl

/* pru_curl-1.c */

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

int main()
{
    char *cmd = "curl https://www.google.com/";

    system(cmd); /* you will get the output of curl on stdout */

    exit(EXIT_SUCCESS);
}

这是 curl 在 shell 调用中使用 &gt; 运算符重定向其输出:

/* pru_curl-2.c */

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

int main()
{
    char *cmd = "curl https://www.google.com/ >output_file-2";

    /* you will get the output of curl on output_file-2 */
    system(cmd);

    exit(EXIT_SUCCESS);
}

另一方面,Curl 允许您指定 -o output_file.txt,一旦程序完成,您就可以读取文件。

/* pru_curl-3.c */

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

int main()
{
    char *cmd = "curl https://www.google.com/ -o output_file-3";

    /* you will get the output of curl on output_file-3 */
    system(cmd);

    exit(EXIT_SUCCESS);
}

您还有第三种选择,即使用popen(3),它允许您将程序作为子命令启动,并从您从popen(3) 获得的FILE * 描述符中读取该程序的输出。你可以这样使用它(逐个字符处理):

/* pru_curl-4.c */

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

int main()
{
    char *cmd = "curl https://www.google.com/";

    FILE *f = popen(cmd, "r");
    if (!f) {
        fprintf(stderr, "%s: %s\n",
            cmd, strerror(errno));
        exit(EXIT_FAILURE);
    }

    int c;
    while((c = fgetc(f)) != EOF) {
        printf("[%d]", c); /* you will get the downloaded file as
                            * sequences of numbers (the character
                            * values) embedded in square brackets on
                            * stdout */
    }
    pclose(f);

    exit(EXIT_SUCCESS);
}

或(逐行处理):

/* pru_curl-5.c */

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

int main()
{
    char *cmd = "curl https://www.google.com/";

    FILE *f = popen(cmd, "r");
    if (!f) {
        fprintf(stderr, "%s: %s\n",
            cmd, strerror(errno));
        exit(EXIT_FAILURE);
    }

    char line[256];
    while (fgets(line, sizeof line, f)) {
        /* you'll get your output in chunks of one line, or 256 bytes
         * ---if longer---, encapsulated by a pair of square brackets
         * drawn in a different color (gren, by the escape sequences
         * used) */
        fprintf(stderr,
            "\033[1;33m[\033[m%s\033[32m]\033[m",
            line);
    }
    pclose(f);

    exit(EXIT_SUCCESS);
}

或(按块):

/* pru_curl-6.c */

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

#define N 8 /* blocks in buffer */
#define CPB 11 /* chars per block */

int main()
{
    char *cmd = "curl https://www.google.com/";

    FILE *f = popen(cmd, "r");
    if (!f) {
        fprintf(stderr, "%s: %s\n",
            cmd, strerror(errno));
        exit(EXIT_FAILURE);
    }

    char block[N][CPB];
    int n;
    char *sep = "";
    do {
        /* print a blanck line between groups */
        printf("%s", sep);
        sep = "\n";

        /* we read as many CPB byte blocks as possible to fill the
         * N registers in buffer.
         * Then we start again until we don't fill completely the
         * buffer. */
        n = fread(block, sizeof block[0], N, f);

        int i;
        for (i = 0; i < n; i++) {
            printf("[%.*s]\n", (int)sizeof block[i], block[i]);
        }

        printf("finished one loop of %d blocks of %d chars, each.\n",
                N, (int) sizeof block[0]);
    } while (n == N);
    /* n < N, so we are finished, check that probably the last register is
     * not printed because it was not complete. */
    pclose(f);

    exit(EXIT_SUCCESS);
}

(所有这些示例都是完整的,并且在发布前已经过测试)


编辑

我已经完成了六个程序的代码,现在它们都是可执行的,只需构建:

$ cc pru_curl-<i>.c -o pru_curl-<i>   # <i> is the program number
$ _

在每种情况下,您都可以通过运行来执行程序:

$ pru_curl-<i>
....  <-- a lot of output (or to a file) about the contents of the root page of google.
$ _

【讨论】:

  • 我试过 curl 和 -o 但没有任何改变,我使用 lynx 和 -dump 所以它不是交互式的......我不明白为什么它不起作用,我尝试了 popen也是,但它不起作用
  • @xcocco,相信我说它不起作用是不够的。我在发布之前已经测试了我的代码,所以请记录下它对您来说意味着什么它不起作用你期望代码做什么你会得到什么。
  • 我知道这段代码适用于 linux 程序,但是当从 android 应用程序执行这段代码时,这段代码不起作用......对我不起作用意味着它没有做我应该做的事情这样做是因为当这段代码从 linux 程序运行时,它会用你说的任何内容填充文件,但从 android 应用程序会创建空文件。
  • 当您调用程序时,您可能已经将标准输出重定向到其他地方。 Android 有一个 linux 内核,因此预计不会有太大的行为差异。 popen 解决方案让您有机会将输出重定向到您的程序,就像我对所有使用它的程序所做的那样。但同样,不起作用是你唯一能说的。
  • 我不想让你看起来很糟糕,很抱歉,无论如何如果流被重定向到其他地方,为什么它会在我说的任何地方创建空文件?感谢您的回答
猜你喜欢
  • 2010-12-03
  • 2010-12-22
  • 2012-04-04
  • 2011-11-30
  • 2011-03-10
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多