程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> linux c法式中獲得shell劇本輸入的完成辦法

linux c法式中獲得shell劇本輸入的完成辦法

編輯:關於C++

linux c法式中獲得shell劇本輸入的完成辦法。本站提示廣大學習愛好者:(linux c法式中獲得shell劇本輸入的完成辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是linux c法式中獲得shell劇本輸入的完成辦法正文


1. 媒介
Unix界有一句名言:“一行shell劇本勝過萬行C法式”,固然這句話有些誇大,但弗成否定的是,借助劇本確切可以或許極年夜的簡化一些編程任務。好比完成一個ping法式來測試收集的連通性,完成ping函數須要寫上200~300行代碼,為何不克不及直接挪用體系的ping敕令呢?平日在法式中經由過程 system函數來挪用shell敕令。然則,system函數僅前往敕令能否履行勝利,而我們能夠須要取得shell敕令在掌握台上輸入的成果。例如,履行內部敕令ping後,假如履行掉敗,我們願望獲得ping的前往信息。

2. 應用暫時文件
起首想到的辦法就是將敕令輸入重定向到一個暫時文件,在我們的運用法式中讀取這個暫時文件,取得內部敕令履行成果,代碼以下所示:

#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);
}

這類應用應用了暫時文件作為運用法式和內部敕令之間的接洽橋梁,在運用法式中須要讀取文件,然後再刪除該暫時文件,比擬繁瑣,長處是完成簡略,輕易懂得。有無不借助暫時文件的辦法呢?

3. 應用匿名管道
在<<UNIX情況高等編程>>一書中給出了一種經由過程匿名管道方法將法式成果輸入到分頁法式的例子,是以想到,我們也能夠經由過程管道來將內部敕令的成果同運用法式銜接起來。辦法就是fork一個子過程,並創立一個匿名管道,在子過程中履行shell敕令,並將其尺度輸入dup 到匿名管道的輸出端,父過程從管道中讀取,便可取得shell敕令的輸入,代碼以下:

/**   * 加強的system函數,可以或許前往system挪用的輸入   *
* @param[in] cmdstring 挪用內部法式或劇本的敕令串
* @param[out] buf 前往內部敕令的成果的緩沖區
* @param[in] len 緩沖區buf的長度
*   * @return 0: 勝利; -1: 掉敗    */
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. 應用popen
在進修unix編程的進程中,發明體系還供給了一個popen函數,可以異常簡略的處置挪用shell,其函數原型以下:
FILE *popen(const char *command, const char *type);
該函數的感化是創立一個管道,fork一個過程,然後履行shell,而shell的輸入可以采取讀取文件的方法取得。采取這類辦法,既防止了創立暫時文件,又不受輸入字符數的限制,推舉應用。
popen應用FIFO管道履行內部法式。

#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);

popen 經由過程type是r照樣w肯定command的輸出/輸入偏向,r和w是絕對command的管道而言的。r表現command從管道中讀入,w表現 command經由過程管道輸入到它的stdout,popen前往FIFO管道的文件流指針。pclose則用於應用停止後封閉這個指針。
上面看一個例子:

#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) );//初始化buf,以避免前面寫如亂碼到文件中
stream = popen( "ls -l", "r" ); //將“ls -l”敕令的輸入 經由過程管道讀取(“r”參數)到FILE* stream
wstream = fopen( "test_popen.txt", "w+"); //新建一個可寫的文件
fread( buf, sizeof(char), sizeof(buf), stream); //將方才FILE* stream的數據流讀取到buf中
fwrite( buf, 1, sizeof(buf), wstream );//將buf中的數據寫到FILE    *wstream對應的流中,也是寫到文件中
pclose( stream );
fclose( wstream );
return 0;
}
[root@localhost src]# gcc popen.c
[root@localhost src]# ./a.out
[root@localhost src]# cat test_popen.txt

總計 128
-rwxr-xr-x 1 root root 5558 09-30 11:51 a.out
-rwxr-xr-x 1 root root 542 09-30 00:00 child_fork.c
-rwxr-xr-x 1 root root 480 09-30 00:13 execve.c
-rwxr-xr-x 1 root root 1811 09-29 21:33 fork.c
-rwxr-xr-x 1 root root 162 09-29 18:54 getpid.c
-rwxr-xr-x 1 root root 1105 09-30 11:49 popen.c
-rwxr-xr-x 1 root root 443 09-30 00:55 system.c
-rwxr-xr-x 1 root root    0 09-30 11:51 test_popen.txt
-rwxr-xr-x 1 root root 4094 09-30 11:39 test.txt

5. 小結
有統計數據注解,代碼的缺點率是必定的,與所應用的說話有關。Linux供給了許多的適用對象和劇本,在法式中挪用對象和劇本,無疑可以簡化法式,從而下降代碼的缺點數量。Linux shell劇本也是一個壯大的對象,我們可以依據須要編制劇本,然後在法式中挪用自界說劇本。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved