Tag: System replace does not have ls-l buffer null shell anonymous pipe limit
Reprinted from http://blog.csdn.net/hjxhjh/article/details/7909518
1. Preface
The Unix world has a famous saying: "A line of shell script is better than Mangyo C program", although this sentence is somewhat exaggerated, but it is undeniable that the use of scripts can greatly simplify some of the programming work. For example, to implement a ping program to test the connectivity of the network, the implementation of the PING function needs to write the 200~300 line code, why not directly call the System ping command? Shell commands are typically invoked in a program through the system function. However, thesystem function returns only if the command succeeds, and we may need to get the result of the shell command output on the console. For example, if execution fails after the external command ping is executed, we want to get the return information for the ping.
2. Using temporary files
The first idea is to redirect the command output to a temporary file, read the temporary file in our application, get the result of the external command execution, and the code looks like this:
#define Cmd_str_len 1024
int Mysystem (char* cmdstring, char* tmpfile)
{
Char Cmd_string[cmd_str_len];
Tmpnam (tmpfile);
sprintf (cmd_string, "%s >%s", cmdstring, tmpfile);
Return system(cmd_string);
}
This use of temporary files as a bridge between the application and external commands, in the application need to read the file, and then delete the temporary file, the more cumbersome, the advantage is simple, easy to understand. Is there a way to not use temporary files?
3. Using Anonymous Pipelines
In the <<unix environment Advanced Programming >> a book gives an example of the output of program results to a pager through an anonymous pipeline, so it is thought that we can also connect the results of external commands to the application through a pipeline. The method is to fork a child process, create an anonymous pipe, execute the shell command in the child process, and set its standard output to the input of the anonymous pipe, and the parent process reads from the pipe to get the output of the shell command, the code is as follows:
/**
* Enhancedsystemfunction that can returnsystemCalled byOutput
*
* @param [in] cmdstring call the command string of an external program or script
* @param [out] buf returns the buffer of the result of the external command
* @param [in] len buffer buf length
*
* @return 0: Success; -1: Failure
*/
int Mysystem (char* cmdstring, char* buf, int len)
{
int fd[2];
pid_t pid;
int n, Count;
memset (buf, 0, Len);
if (pipe (FD) < 0)
return-1;
if ((PID = fork ()) < 0)
return-1;
else if (PID > 0)/*/Parent Process */
{
Close (fd[1]); /* Close Write End */
Count = 0;
while ((n = read (fd[0], buf + count, len)) > 0 && count > Len)
Count + = n;
Close (fd[0]);
if (Waitpid (PID, NULL, 0) > 0)
return-1;
}
else/* Child process */
{
Close (fd[0]); /* Close Read end */
if (fd[1]! = Stdout_fileno)
{
if (Dup2 (fd[1], stdout_fileno)! = Stdout_fileno)
{
return-1;
}
Close (fd[1]);
}
if (Execl ("/bin/sh", "sh", "-C", Cmdstring, (char*) 0) = = =-1)
return-1;
}
return 0;
}4. Using Popen
In the process of learning UNIX programming, the discovery system also provides a popen function, which can be very simple to process the call shell, its function prototype is as follows:
FILE *popen (const char *command, const char *type);
The function is to create a pipeline, fork a process, and then execute the shell, and the shell's output can be obtained by reading the file. In this way, it is recommended to avoid creating temporary files and not being limited by the number of output characters.
Popen executes external programs using FIFO pipelines.
#include <stdio.h>
FILE *popen (const char *command, const char *type);
int Pclose (FILE *stream);
Popen type is R or W to determine command input/OutputDirection, R and W are relative command pipes. R means the command is read in from the pipe, w means command through the pipeOutputTo its Stdout,popen returns a file stream pointer to the FIFO pipeline. The pclose is used to close the pointer after the end of use.
Let's look at an example:
/*******************************************************************************************
* * NAME:POPEN.C
Used to show the usage of Popen ().
* * Author:zieckey, ([email protected])
* * DATE:2007/9/30 11:47
* * All rights reserved!
*******************************************************************************************/
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main (void)
{
FILE *stream;
FILE *wstream;
Char buf[1024];
memset (buf, ' n ', sizeof (BUF));//Initialize the BUF to avoid writing in the file as garbled
stream = Popen ("Ls-l", "R"); The "ls-l" command isOutputRead by pipe ("r" parameter) to file* stream
Wstream = fopen ("Test_popen.txt", "w+"); Create a new writable file
Fread (buf, sizeof (char), sizeof (BUF), stream); Reads the data stream just file* stream into buf
Fwrite (buf, 1, sizeof (BUF), wstream);//writes data from BUF to the stream corresponding to file *wstream
Pclose (stream);
Fclose (Wstream);
return 0;
}
5. Summary
Statistical data show that the defect rate of the code is certain, regardless of the language used. Linux provides a lot of utilities and scripts to invoke tools and scripts in the program, which can undoubtedly simplify the program, thereby reducing the number of defects in the code. The Linux shell script is also a powerful tool, and we can script it as needed, and then invoke the custom script in the program.
Inux C program to get shell script output (such as get system command output)