【问题标题】:Why is the following shell command working when executed directly in command line, but not working when executed through C program using popen/system?为什么以下 shell 命令在命令行中直接执行时有效,但在使用 popen/system 通过 C 程序执行时无效?
【发布时间】:2019-09-27 18:28:48
【问题描述】:

命令是:ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R'

我通过 adb shell 运行它。基本上,我想要一个当前在运行队列中的进程(和某些参数)列表。如果我直接通过 shell 运行它就可以正常工作。

但是,如果我将它放在 C 程序中并交叉编译以在 Android 上运行,它就不起作用。只有ps -c -p 在工作(我已经检查过了)。但是在运行这个ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R' 时,我得到了输出:

usage: tr [-cds] SET1 [SET2]

Translate, squeeze, or delete characters from stdin, writing to stdout

-c/-C  Take complement of SET1
-d     Delete input characters coded SET1
-s     Squeeze multiple output characters of SET2 into one character

tr: Needs 1 argument
usage: cut OPTION... [FILE]...

Print selected parts of lines from each FILE to standard output.

-b LIST select only these bytes from LIST.
-c LIST select only these characters from LIST.
-f LIST select only these fields.
-d DELIM    use DELIM instead of TAB for field delimiter.
-s  do not print lines not containing delimiters.
-n  don't split multibyte characters (Ignored).

cut: Needs -fcb

我认为ps -c -p 的输出没有传送到tr,也没有传送到cut。 你能提出什么问题吗?

这是我正在使用的代码:

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

    #define BUFSIZE 128

    int main(int argc,char **argv)
    {
        char *cmd4 = "ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R'";    
        system(cmd4);

        FILE *fp;


        char buf[BUFSIZE];
     // Another method
    if ((fp = popen(cmd4, "r")) == NULL) {
        printf("Error opening pipe4!\n");
        return -1;
    }

    while (fgets(buf, BUFSIZE, fp) != NULL) {
        // Do whatever you want here...
        printf("cmd 4 running!");
        printf("OUTPUT: %s", buf);
    }

    if(pclose(fp))  {
        printf("Command not found or exited with error status4\n");
        return -1;
    }

    return 0;
}

【问题讨论】:

  • 你能分享在你的 C 程序中调用的代码吗?
  • 进行了编辑。
  • 如果您在 Linux 上,请在 strace 下运行它,使用 -f 选项跟踪所有子进程,并了解命令行参数在通过类似 @ 时会发生什么情况987654332@.
  • 对于怀疑管道正在执行的人,请注意错误消息来自管道的第二和第三阶段,而不是第一阶段。

标签: c linux command-line adb popen


【解决方案1】:

在 shell 中,您正在使用以下命令:

ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R'

在 C 中,您将以下内容传递给 system(然后再传递给 popen):

ps -c -p | tr -s  | cut -d  -f 2,6-10,13 | grep 'R'

看到区别了吗?引号需要在 C 源代码中进行转义。此外,当您遇到此类问题时,请务必输出相关数据,以便您可以看到实际发生的事情,而不是您的计划。一个简单的puts(cmd4) 会立即揭示这一点。

【讨论】:

猜你喜欢
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 2017-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 2022-01-27
相关资源
最近更新 更多