I want to get a Linux command's output string as well as command output status in a C++ program. I am executing Linux commands in my application.
我想在C ++程序中获取Linux命令的输出字符串以及命令输出状态。我在我的应用程序中执行Linux命令。
for example: Command:
例如:命令:
rmdir abcd
Command output string:
命令输出字符串:
rmdir: failed to remove `abcd': No such file or directory
rmdir:无法删除`abcd':没有这样的文件或目录
Command Status:
1 (Which means command has been failed)
1(表示命令失败)
I tried using Linux function system()
which gives the output status, and function popen()
which gives me output string of a command, but neither function gives me both the output string and output status of a Linux command.
我尝试使用Linux函数system()给出输出状态,函数popen()给出了命令的输出字符串,但这两个函数都没有给我输出字符串和Linux命令的输出状态。
5 个解决方案
#1
7
The output string is in standard output or standard error descriptor (1 or 2, respectively).
输出字符串是标准输出或标准错误描述符(分别为1或2)。
You have to redirect these streams (take a look at dup
and dup2
function) to a place, where you can read them (for example - a POSIX pipe
).
您必须将这些流(请参阅dup和dup2函数)重定向到可以读取它们的位置(例如 - POSIX管道)。
In C I'd do something like this:
在C中我会做这样的事情:
int pd[2];
int retValue;
char buffer[MAXBUF] = {0};
pipe(pd);
dup2(pd[1],1);
retValue = system("your command");
read(pd[0], buffer, MAXBUF);
Now, you have (a part of) your output in buffer and the return code in retValue.
现在,您有缓冲区输出(的一部分)和retValue中的返回代码。
Alternatively, you can use a function from exec
(i.e. execve
) and get the return value with wait
or waitpid
.
或者,您可以使用exec中的函数(即execve)并使用wait或waitpid获取返回值。
Update: this will redirect only standard output. To redirect standard error, use dup2(pd[1],1)
.
更新:这将仅重定向标准输出。要重定向标准错误,请使用dup2(pd [1],1)。
#2
3
The simplest solution is to use system
, and to redirect standard out and standard error to a temporarly file, which you can delete later.
最简单的解决方案是使用系统,并将标准输出和标准错误重定向到临时文件,以后可以删除。
#3
2
Unfortunately there's no easy and simple way in C on Linux to do this. Here's an example how to read/write stdout/stderr/stdin of child process correctly.
不幸的是,在Linux上的C中没有简单易行的方法来做到这一点。这是一个如何正确读取/写入子进程的stdout / stderr / stdin的示例。
And when you want to receive exit code you have to use waitpid
(complete example is provided on the bottom of the provided page):
当你想要接收退出代码时,你必须使用waitpid(提供的页面底部提供了完整的示例):
endID = waitpid(childID, &status, WNOHANG|WUNTRACED);
Now you just have to join those two together :)
现在你只需加入这两个:)
There's also a great free book named Advanced Linux Programming (ALP) containing detailed information about these kinds of problem available here.
还有一本名为Advanced Linux Programming(ALP)的免费书籍,其中包含有关此类问题的详细信息。
#4
1
Building on Piotr Zierhoffer answer above, here's a function that does just that, and also restores stdout and stderr their original state.
在上面的Piotr Zierhoffer回答的基础上,这里有一个功能就是这样,并且还恢复了stdout和stderr的原始状态。
// Execute command <cmd>, put its output (stdout and stderr) in <output>,
// and return its status
int exec_command(string& cmd, string& output) {
// Save original stdout and stderr to enable restoring
int org_stdout = dup(1);
int org_stderr = dup(2);
int pd[2];
pipe(pd);
// Make the read-end of the pipe non blocking, so if the command being
// executed has no output the read() call won't get stuck
int flags = fcntl(pd[0], F_GETFL);
flags |= O_NONBLOCK;
if(fcntl(pd[0], F_SETFL, flags) == -1) {
throw string("fcntl() failed");
}
// Redirect stdout and stderr to the write-end of the pipe
dup2(pd[1], 1);
dup2(pd[1], 2);
int status = system(cmd.c_str());
int buf_size = 1000;
char buf[buf_size];
// Read from read-end of the pipe
long num_bytes = read(pd[0], buf, buf_size);
if(num_bytes > 0) {
output.clear();
output.append(buf, num_bytes);
}
// Restore stdout and stderr and release the org* descriptors
dup2(org_stdout, 1);
dup2(org_stderr, 2);
close(org_stdout);
close(org_stderr);
return status;
}
#5
0
you can use popen
system call, it will redirect output to a file and from file you can redirect output to a string. like :
你可以使用popen系统调用,它会将输出重定向到一个文件,你可以从文件中将输出重定向到一个字符串。喜欢 :
char buffer[MAXBUF] = {0};
FILE *fd = popen("openssl version -v", "r");
if (NULL == fd)
{
printf("Error in popen");
return;
}
fread(buffer, MAXBUF, 1, fd);
printf("%s",buffer);
pclose(fd);
For more information read man
page for popen
.
有关更多信息,请阅读popen的手册页。
#1
7
The output string is in standard output or standard error descriptor (1 or 2, respectively).
输出字符串是标准输出或标准错误描述符(分别为1或2)。
You have to redirect these streams (take a look at dup
and dup2
function) to a place, where you can read them (for example - a POSIX pipe
).
您必须将这些流(请参阅dup和dup2函数)重定向到可以读取它们的位置(例如 - POSIX管道)。
In C I'd do something like this:
在C中我会做这样的事情:
int pd[2];
int retValue;
char buffer[MAXBUF] = {0};
pipe(pd);
dup2(pd[1],1);
retValue = system("your command");
read(pd[0], buffer, MAXBUF);
Now, you have (a part of) your output in buffer and the return code in retValue.
现在,您有缓冲区输出(的一部分)和retValue中的返回代码。
Alternatively, you can use a function from exec
(i.e. execve
) and get the return value with wait
or waitpid
.
或者,您可以使用exec中的函数(即execve)并使用wait或waitpid获取返回值。
Update: this will redirect only standard output. To redirect standard error, use dup2(pd[1],1)
.
更新:这将仅重定向标准输出。要重定向标准错误,请使用dup2(pd [1],1)。
#2
3
The simplest solution is to use system
, and to redirect standard out and standard error to a temporarly file, which you can delete later.
最简单的解决方案是使用系统,并将标准输出和标准错误重定向到临时文件,以后可以删除。
#3
2
Unfortunately there's no easy and simple way in C on Linux to do this. Here's an example how to read/write stdout/stderr/stdin of child process correctly.
不幸的是,在Linux上的C中没有简单易行的方法来做到这一点。这是一个如何正确读取/写入子进程的stdout / stderr / stdin的示例。
And when you want to receive exit code you have to use waitpid
(complete example is provided on the bottom of the provided page):
当你想要接收退出代码时,你必须使用waitpid(提供的页面底部提供了完整的示例):
endID = waitpid(childID, &status, WNOHANG|WUNTRACED);
Now you just have to join those two together :)
现在你只需加入这两个:)
There's also a great free book named Advanced Linux Programming (ALP) containing detailed information about these kinds of problem available here.
还有一本名为Advanced Linux Programming(ALP)的免费书籍,其中包含有关此类问题的详细信息。
#4
1
Building on Piotr Zierhoffer answer above, here's a function that does just that, and also restores stdout and stderr their original state.
在上面的Piotr Zierhoffer回答的基础上,这里有一个功能就是这样,并且还恢复了stdout和stderr的原始状态。
// Execute command <cmd>, put its output (stdout and stderr) in <output>,
// and return its status
int exec_command(string& cmd, string& output) {
// Save original stdout and stderr to enable restoring
int org_stdout = dup(1);
int org_stderr = dup(2);
int pd[2];
pipe(pd);
// Make the read-end of the pipe non blocking, so if the command being
// executed has no output the read() call won't get stuck
int flags = fcntl(pd[0], F_GETFL);
flags |= O_NONBLOCK;
if(fcntl(pd[0], F_SETFL, flags) == -1) {
throw string("fcntl() failed");
}
// Redirect stdout and stderr to the write-end of the pipe
dup2(pd[1], 1);
dup2(pd[1], 2);
int status = system(cmd.c_str());
int buf_size = 1000;
char buf[buf_size];
// Read from read-end of the pipe
long num_bytes = read(pd[0], buf, buf_size);
if(num_bytes > 0) {
output.clear();
output.append(buf, num_bytes);
}
// Restore stdout and stderr and release the org* descriptors
dup2(org_stdout, 1);
dup2(org_stderr, 2);
close(org_stdout);
close(org_stderr);
return status;
}
#5
0
you can use popen
system call, it will redirect output to a file and from file you can redirect output to a string. like :
你可以使用popen系统调用,它会将输出重定向到一个文件,你可以从文件中将输出重定向到一个字符串。喜欢 :
char buffer[MAXBUF] = {0};
FILE *fd = popen("openssl version -v", "r");
if (NULL == fd)
{
printf("Error in popen");
return;
}
fread(buffer, MAXBUF, 1, fd);
printf("%s",buffer);
pclose(fd);
For more information read man
page for popen
.
有关更多信息,请阅读popen的手册页。