执行 bash 命令并在 C 中获取输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14393762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 04:17:38  来源:igfitidea点击:

Executing bash command and getting the output in C

clinuxbashcommand

提问by Sarp Kaya

Hello I have seen some solutions on the internet, all of them are basically creating a file, however I want to store them in an array of char. Speed is really important for me and I don't want to spend any time for working on hard drive. So popen()is not a real solution for me.

您好,我在互联网上看到了一些解决方案,它们基本上都是创建一个文件,但是我想将它们存储在一个字符数组中。速度对我来说真的很重要,我不想花任何时间在硬盘上工作。所以popen()对我来说不是一个真正的解决方案。

回答by Oleksandr Kravchuk

Here is a working code snippet:

这是一个工作代码片段:

char bash_cmd[256] = "ls -l":
char buffer[1000];
FILE *pipe;
int len; 

pipe = popen(bash_cmd, "r");

if (NULL == pipe) {
    perror("pipe");
    exit(1);
} 

fgets(buffer, sizeof(buffer), pipe);

len = strlen(bash_cmd);
buffer[len-1] = '
system("YourCommand | SecondProgram");
'; pclose(pipe);

回答by vonbrand

Never forget Knuth's saying that "premature optimization is the root of all evil". Don't worry about performance until it matters, and then measurebefore doing anything. Except for very rare situations, the value of your time is much higher than the cost of the program runs.

永远不要忘记 Knuth 所说的“过早的优化是万恶之源”。在重要之前不要担心性能,然后在做任何事情之前进行测量。除了极少数情况外,您的时间价值远高于程序运行的成本。

Jon Bentley's "Writing efficient programs" (sadly out of print, in his "Programming Pearls"one chapter is a summary) is a detailed discussion on how to make programs run faster (if it is worthwhile); and only as the very last measure, to squeeze out the last possible 2% of performance (after cutting run time down by half) it recommends using changes like you propose. The cited book includes some very entertaining war stories of "performance optimizations" that were a complete waste (optimize code that isn't ever used, oprimize the code run while the operating system twiddles its thumbs, ...).

Jon Bentley 的“编写高效的程序”(遗憾的是已绝版,在他的“Programming Pearls”一章是总结)详细讨论了如何使程序运行得更快(如果值得的话);并且仅作为最后一项措施,为了挤出最后可能的 2% 的性能(在将运行时间减少一半之后),它建议使用您建议的更改。所引用的书包括一些非常有趣的“性能优化”War故事,这些故事完全是浪费(优化从未使用过的代码,优化运行的代码,而操作系统却在玩弄它的拇指,......)。

回答by Andreas Grapentin

If you would read the manpage of popen, you would notice the following:

如果您阅读 popen 的联机帮助页,您会注意到以下内容:

The popen() function opens a process by creating a pipe, forking, and invoking the shell. [...] The return value from popen() is a normal standard I/O stream in all respects save that it must be closed with pclose() rather than fclose(3). [...] reading from a "popened" stream reads the command's standard output, and the command's standard input is the same as that of the process that called popen().

popen() 函数通过创建管道、分叉和​​调用外壳来打开一个进程。[...] popen() 的返回值在所有方面都是一个普通的标准 I/O 流,除了它必须用 pclose() 而不是 fclose(3) 关闭。[...]从“popened”流读取命令的标准输出,命令的标准输入与调用 popen() 的进程的标准输入相同。

(emphasis mine)

(强调我的)

As you can see, a call to popenresults in the stdoutof the command being piped into your program through an I/O stream, which has nothing to do with disk I/O at all, but rather with interprocess communication managed by the operating system.

如您所见,对 的调用popen导致stdout命令通过I/O 流通过管道传输到您的程序中,这与磁盘 I/O 完全无关,而是与操作系统管理的进程间通信有关。

(As a sidenote: It's generally a good idea to rely on the basic functionality of the operating system, within reason, to solve common problems. And since popenis part of POSIX.1-2001you can rely on it to be available on all standards compliant operarting systems, even windows)

(作为旁注:在合理范围内,依靠操作系统的基本功能来解决常见问题通常是一个好主意。因为这popenPOSIX.1-2001您可以依赖它在所有符合标准的操作系统上可用的一部分,即使视窗)

EDIT: if you want to know more, read this: http://linux.die.net/man/3/popen

编辑:如果您想了解更多信息,请阅读:http: //linux.die.net/man/3/popen

回答by rockdaboot

If speed is important to you, you can write your own version of popen.

如果速度对您很重要,您可以编写自己的 popen 版本。

It may make sense, since popen() - creates a pipe - forks - executes the shell (very expensive!) - the shell than creates a pipe, forks, executes your program

这可能是有道理的,因为 popen() - 创建一个管道 - 分叉 - 执行外壳(非常昂贵!) - 外壳比创建管道,分叉,执行你的程序

Your customized version could reduce the procedure to: - creates a pipe - forks - executes your program

您的自定义版本可以将程序简化为: - 创建管道 - 分叉 - 执行您的程序

You could even extend popen to control the commands STDOUT, STDERR and STDIN seperately. I wrote such a routine, see https://github.com/rockdaboot/mget/blob/master/libmget/pipe.cIt is GPL'ed.

您甚至可以扩展 popen 来分别控制命令 STDOUT、STDERR 和 STDIN。我写了这样一个例程,见https://github.com/rockdaboot/mget/blob/master/libmget/pipe.c是GPL的。

You call mget_popen3() with FILE pointers or mget_fd_popen3() with file descriptors. At least, it should give you an idea on how to do it.

您可以使用 FILE 指针调用 mget_popen3() 或使用文件描述符调用 mget_fd_popen3() 。至少,它应该让你知道如何去做。

回答by PaulDaviesC

Do you mind having more than one C programs?If you don't ,you can make use of the command line arguments. In the fist C program you can do the following

你介意有多个 C 程序吗?如果你不介意,你可以使用命令行参数。在第一个 C 程序中,您可以执行以下操作

main(int argc,char *argv[])

The SecondProgramwill be the "executable" of the second C program you will be writing. In the second C program you can receive the output of the command YourCommandas a command line argument in the SecondProgram. For that purpose you may begin the main() of second C program as below

SecondProgram会是你会写第二个C程序的“可执行”。在第二个 C 程序中,您可以接收命令的输出YourCommand作为SecondProgram. 为此,您可以开始第二个 C 程序的 main(),如下所示

##代码##

The array argvwill have the output of the YourCommandand argcwill contain the number of elements in the array argv.

该阵列argv将具有的输出YourCommandargc将包含在数组中的元素数argv