使用popen时出现“命令未找到”的错误

3

我正在使用C语言编程,当调用以下参数的popen函数时遇到了问题:

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

当我使用这种方式调用popen时,会出现以下消息:
alias: -p not found

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

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

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

也许有人会意识到实际上出了什么问题。

2个回答

4
alias 命令是内置于 shell 中的。 popensystem() 类似,会调用 /bin/sh 来执行指定的命令。你的交互式 shell 可能是 bash,它支持 -p 选项来设置 alias。而 /bin/sh 则根据你的系统配置可能不支持该选项。
无论如何,即使此方法可以工作,它也不会给你任何有用的信息。popen() 调用会启动一个新 shell,并且(再次根据你的配置)由于它不是交互式 shell,很可能不会设置你的别名。 ls -i 命令有效是因为 ls 是外部命令,所以它无论是从 bash 还是 /bin/sh,或者是在交互式或非交互式 shell 中调用都是一样的。(有时 ls 可能被定义为别名或 shell 函数,但这样的定义通常不会干扰使用 -i 选项)。

1

alias 不是可执行程序,而是一个 shell 内置命令(可以将其视为 bash 脚本语言中的“函数”),因此您无法使用此名称打开进程。您可以尝试欺骗 bash 并将其作为管道。类似于此未经测试的代码片段:

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既存在于内置程序中,也存在于外部程序中。

1
如果您以“r”模式打开一个管道,则无法向其打印,只能从其中读取。请使用命令“/ bin / bash -c'alias-p'”。 - Barmar
1
错误。popen() 通过 /bin/sh 调用命令,因此例如 popen("alias", "r") 将起作用(尽管它可能不会产生任何输出)。问题在于 /bin/shalias 命令不支持 -p 选项。请参见我的答案。 - Keith Thompson
这种方法假定您既可以向/bin/bash提供输入,又可以收集其输出。虽然可行,但不能通过简单的pipe()调用实现。此外,在大多数shell中,ls不是内置命令。 - Keith Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接