1. Preface
There is a famous saying in UNIX: "A shell script is better than a million lines of C Programs, script can greatly simplify some programming work. For example, to implement a Ping program to test network connectivity, write 200 ~ to implement the Ping function ~ Why can't I directly call the ping command of the System for the first line of code? Generally, shell commands are called through the system function in the program. However, the system function only returns whether the command is successfully executed, and we may need to obtain the result output by the shell command on the console. For example, if the ping command fails, we want to get the ping response.
2. Use temporary files
The first method is to redirect the command output to a temporary file, read the temporary file in our application, and obtain the external command execution result. The Code is as follows:
# Define pai_str_len 1024
Int mysystem (char * struct string, char * tmpfile)
{
Char character _string [character _str_len];
Tmpnam (tmpfile );
Sprintf (optional _string, "% S> % s", optional string, tmpfile );
Return System (pai_string );
}
The temporary file is used as a bridge between the application and external commands, and the file needs to be read and deleted in the application, which is cumbersome and easy to implement, easy to understand. Is there any way to avoid using temporary files?
3. Use an anonymous Pipeline
The <advanced programming in UNIX environment> book provides an example of outputting program results to paging programs through anonymous pipelines, we can also connect the results of external commands with the application through pipelines. The method is to fork a sub-process, create an anonymous pipeline, execute shell commands in the sub-process, and output DUP to the input end of the anonymous pipeline. The parent process reads data from the pipeline, to obtain the output of the shell command, the Code is as follows:
/*** The enhanced system function can return the output of the system call *
* @ Param [in] using string refers to the command string for calling an external program or script
* @ Param [out] Buf returns the buffer of the external command result
* @ Param [in] Len buffer Buf Length
** @ Return 0: Successful;-1: Failed */
Int mysystem (char * character string, 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", character string, (char *) 0) =-1)
Return-1;
}
Return 0;
}
4. Use popen
In the process of learning Unix programming, it is found that the system also provides a popen function, which can easily process shell calls. Its function prototype is as follows:
File * popen (const char * command, const char * type );
This function is used to create a pipeline, fork a process, and then execute shell. The shell output can be obtained by reading files. This method avoids the creation of temporary files and is not limited by the number of output characters. We recommend that you use this method.
Popen uses a FIFO pipeline to execute external programs.
# Include <stdio. h>
File * popen (const char * command, const char * type );
Int pclose (File * stream );
Popen determines the input/output direction of a command through whether the type is R or W. R and W are relative to the command pipeline. R indicates that the command is read from the pipeline, W indicates that the command is output to its stdout through the pipeline, and popen returns the file stream pointer of the FIFO pipeline. Pclose is used to close the pointer after use.
The following is an example:
# 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, '\ 0', sizeof (BUF); // initialize the Buf to avoid gibberish in the file.
Stream = popen ("ls-L", "R"); // read the output of the "ls-L" command through the pipeline ("R" parameter) to file * stream
Wstream = fopen ("test_popen.txt", "W +"); // create a writable file
Fread (BUF, sizeof (char), sizeof (BUF), stream); // read the data stream of file * stream to Buf.
Fwrite (BUF, 1, sizeof (BUF), wstream); // write the data in the Buf to the stream corresponding to file * wstream, which is also written to the file
Pclose (Stream );
Fclose (wstream );
Return 0;
}
[Root @ localhost SRC] # GCC popen. c
[Root @ localhost SRC] #./A. Out
[Root @ localhost SRC] # Cat test_popen.txt
Total 128
-Rwxr-XR-x 1 Root 5558 09-30 a. Out
-Rwxr-XR-x 1 Root 542 09-30 child_fork.c
-Rwxr-XR-x 1 Root 480 09-30 execve. c
-Rwxr-XR-x 1 Root 1811 09-29 21:33 fork. c
-Rwxr-XR-x 1 Root 162 09-29 getpid. c
-Rwxr-XR-x 1 Root 1105 09-30 popen. c
-Rwxr-XR-x 1 Root 443 09-30 system. c
-Rwxr-XR-x 1 Root 0 09-30 :51 test_popen.txt
-Rwxr-XR-x 1 Root 4094 09-30 test.txt
5. Summary
Statistics show that the defect rate of the Code is certain and has nothing to do with the language used. Linux provides many utility tools and scripts. Calling tools and scripts in a program can undoubtedly simplify the program and reduce the number of defects in the code. Linux Shell script is also a powerful tool. We can compile scripts as needed and then call custom scripts in the program.
This article comes from:Http://linux.chinaitlab.com/c/805920.html
Collect and organize it labs in ChinaRegion name