【问题标题】:Command not found when using popen使用 popen 时找不到命令
【发布时间】:2016-06-07 17:49:48
【问题描述】:

我正在使用 C 语言,在使用以下参数调用 popen 时遇到问题:

void exampleFunction(void)
{
    .
    .
    .
    FILE* in = popen("alias -p", "r");
    .
    .
    .
}

当我以这种方式致电popen 时,我收到以下消息:

alias: -p not found

我不知道实际出了什么问题,因为当我使用以下参数调用 popen 时:

FILE* in = popen("ls -i", "r");

没有问题,我使用的是相同的语法。

也许有人意识到真正的问题。

【问题讨论】:

    标签: c linux system-calls popen


    【解决方案1】:

    alias 命令内置在 shell 中。

    popensystem() 一样,调用/bin/sh 来执行指定的命令。您的交互式 shell 可能是 bash,它支持 -palias 的选项。 /bin/sh,根据您的系统配置,可能不会。

    无论如何,即使这有效,它也不会为您提供任何有用的信息。 popen() 调用将调用一个新的 shell,并且(同样,取决于您的配置)它可能不会设置您的别名,因为它不是交互式 shell。

    ls -i 命令有效,因为ls 是一个外部命令,因此无论是从bash/bin/sh,还是从交互式或非交互式shell 调用它,它的工作方式都是相同的。 (有时ls 可以定义为别名或shell 函数,但这样的定义通常不会干扰-i 选项的使用。)

    【讨论】:

      【解决方案2】:

      alias 不是可执行程序,而是内置的 shell(将其视为“bash 脚本语言中的函数”),因此您无法使用此名称打开进程。您可以尝试欺骗 bash 并将其通过管道输入。像这样未经测试的 sn-p:

      FILE* p = popen("/bin/bash", "r"); // Note: on non-Linux-systems you might need another path or rely on $PATH
      fprintf(p, "alias -p\n");
      

      请注意,您也不能直接调用别名。 与ls 的区别在于ls 两者都存在,作为内置的as 程序。

      【讨论】:

      • 如果你用r模式打开一个管道,你不能打印到它,只能从中读取。使用命令/bin/bash -c 'alias -p'
      • 不正确。 popen() 通过/bin/sh 调用命令,因此例如popen("alias", "r") 可以工作(尽管它可能不会产生任何输出)。问题是/bin/shalias 命令不支持-p 选项。看我的回答。
      • 此方法假定您既可以将输入提供给/bin/bash,又可以收集其输出。这是可行的,但不是通过简单的pipe() 调用。此外,ls 在大多数 shell 中不是内置命令。
      猜你喜欢
      • 2011-03-16
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      • 2012-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多