欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

函数 —— popen() fscanf() sprintf() 执行shell命令并获取结果

发布时间:2025/10/17 34 豆豆
生活随笔 收集整理的这篇文章主要介绍了 函数 —— popen() fscanf() sprintf() 执行shell命令并获取结果 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

对fopen()函数的理解如下:

表头文件

#include<stdio.h>

定义函数

FILE * popen( const char * command,const char * type);

函数说明

popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c来执行参数command的指令。参数type可使用“r”代表读取,“w”代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子进程的标准输入设备中。此外,所有使用文件指针(FILE*)操作的函数也都可以使用,除了fclose()以外。

  • 如果 type 为 r,那么调用进程读进 command 的标准输出。
  • 如果 type 为 w,那么调用进程写到 command 的标准输入。

返回值

若成功则返回文件指针,否则返回NULL,错误原因存于errno中。

错误代码

EINVAL参数type不合法。

注意事项

在编写具SUID/SGID权限的程序时请尽量避免使用popen(),popen()会继承环境变量,通过环境变量可能会造成系统安全的问题。

范例

1

2

3

4

5

6

7

8

9

10

11

#include<stdio.h>

 

main()

{

    FILE *fp;

    char buffer[80];

    fp = popen("cat /etc/passwd", "r");

    fgets(buffer, sizeof(buffer), fp);

    printf("%s", buffer);

    pclose(fp);

}

执行

root :x:0 0: root: /root: /bin/bash


对sprintf()函数的理解如下:

表头文件

#include<stdio.h>

定义函数

int   sprintf( char *string,char * farmat [,argument,...]);

函数说明

sprintf指的是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数。

返回值

返回写入string 的字符数,出错则返回-1. 如果 string或 format 是空指针,且不出错而继续,函数将返回-1,并且 errno 会被设置为 EINVAL。

sprintf 返回以format为格式argument为内容组成的结果被写入buffer 的字节数,结束字符‘\0’不计入内。即,如果“Hello”被写入空间足够大的buffer后,函数sprintf 返回5. 

同时buffer的内容将被改变

错误代码

EINVAL参数type不合法。

注意事项

使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性。

范例

1

2

3

4

5

6

7

8

9

10

11

#include<stdio.h>

 

int main()

{

    char buf[100] = {0};

    char *who = "I";

    char *whom = "CSDN";

     int count = 0;

 

    count = sprintf(buf,"%s love %s",who,whom);

    printf("%s\n",buf);

    printf("%d\n", count);

    pclose(fp);

}

执行

I love CSDN

11

如何在sprintf中打印“双引号?%百分号? #include <stdio.h> #include <time.h> int main() {char s[80];sprintf(s,"% %\""); //转义字符方法printf("%s\n",s); //%"sprintf(s,"%c %c",'%','"');//字符常量方法printf("%s\n",s); //% "return 0; }

 

对fscanf()函数的理解如下:

表头文件

#include<stdio.h>

定义函数

int fscanf(FILE*stream,constchar*format,[argument...]);

函数说明

从一个流中执行格式化输入,fscanf遇到空格和换行时结束,注意空格时也结束。这与fgets有区别,fgets遇到空格不结束。

返回值

整型,成功返回读入的参数的个数,失败返回EOF(-1)

 

 

注意事项

fscanf遇到空格和换行时结束,注意空格时也结束

范例

#include <stdio.h> #include <stdlib.h>int main() {char str1[10], str2[10], str3[10];int year;FILE * fp; int count = 0;fp = fopen ("file.txt", "w+");fputs("We are in 2014", fp);rewind(fp);count = fscanf(fp, "%s %s %s %d", str1, str2, str3, &year);printf("Read String1 |%s|\n", str1 );printf("Read String2 |%s|\n", str2 );printf("Read String3 |%s|\n", str3 );printf("Read Integer |%d|\n", year );printf("Count |%d|\n", count ); fclose(fp);return(0); } <stdio.h> #include <stdlib.h>int main() {char str1[10], str2[10], str3[10];int year;FILE * fp; int count = 0;fp = fopen ("file.txt", "w+");fputs("We are in 2014", fp);rewind(fp);count = fscanf(fp, "%s %s %s %d", str1, str2, str3, &year);printf("Read String1 |%s|\n", str1 );printf("Read String2 |%s|\n", str2 );printf("Read String3 |%s|\n", str3 );printf("Read Integer |%d|\n", year );printf("Count |%d|\n", count ); fclose(fp);return(0); }

执行

Read String1 |We|

Read String2 |are|

Read String3 |in|

Read Integer |2014|

Count |4|

 简单的使用--1:
       问题描述:opoen函数执行,shell命令中的cat命令,并用fscanf函数获取查找到的值

 

int main() {FILE *fp;char cmd[255] = {0};char tmp[255] = {0};sprintf(cmd,"cat /etc/passwd");printf("cmd == %s\n",cmd); //cmd == cat /etc/passwdfp = popen(cmd,"r");fscanf(fp,"%s",tmp);printf("tmp=%s strlen(tmp)=%d\n",tmp,strlen(tmp)); //tmp=root:x:0:0:root:/root:/bin/bash strlen(tmp)=31 pclose(fp); }

简单的使用--2:

    问题描述:查找文件中的某个字段,存在则重写,不存在则加入最后一行。

#include<stdio.h> #include<stdio.h> #include<stdlib.h> #define TEST_CONFIG "test.conf"int main() {FILE *fp;char *cmd = (char*)malloc(sizeof(char)*128);int input = 0;int line = 0;printf("Please input you want to find number:");scanf("%d",&input);//sprintf(cmd,"cat %s | awk '{print $1}' | grep -v '^\\$' | grep -v '^#' | grep -n '^%d$'",TEST_CONFIG,input);sprintf(cmd,"cat %s | awk '{print $1}'| grep -n '^%d$'",TEST_CONFIG,input); // 需要\字符使用\\来代替 '^str$'grep中:^匹配以str开头,$匹配以str结尾(严格匹配)printf("%s\n",cmd);fp = popen(cmd,"r");fscanf(fp,"%d",&line);printf("line == %d\n",line);pclose(fp);if(line != 0) //exist , rewrite ==》 input+1{printf("exit!\n");sprintf(cmd,"sed -i '%dc %d' %s",line,input+1,TEST_CONFIG);}else{printf("bb\n");sprintf(cmd,"sed -i '$a%d' %s",input,TEST_CONFIG);printf("%s\n",cmd);}fp = popen(cmd,"r");pclose(fp);free(cmd);return 0; } /*结果如下所示:***test.conf $11 #44 55***./a.out Please input you want to find number:55 cat test.conf | awk '{print $1}'| grep -n '^55$' line == 3 exit!***result $11 #44 56***./a.out cat test.conf | awk '{print $1}'| grep -n '^77$' line == 0 bb sed -i '$a77' test.conf***result $11 #44 56 77 */

简单的使用--2:

    问题描述:替换文件中的某一列的值

    asdfgh popen.txt             《--【 文件该之前】                       asdfgh popen

    qwerty popen.c                 【文件该之后】--》                       qwerty popen
 

#include <stdio.h> int main() {FILE *fp;char cmd[255] = {0};char line[255] = {0};char newline[255] = {0};int i = 1, j = 1;sprintf(cmd,"cat popen.txt");printf("%s\n",cmd);fp = popen(cmd,"r");if(NULL == fp){return 1;}while(NULL != fgets(line,sizeof(line),fp)) {printf("line[%d] = %s",i,line); i++;}pclose(fp);//替换文件中的第二列 全部为popen, [[ popen引号需要转义]] [[mv时候加-f取消 提示输入y/n]] //[[并且要加cat命令 否则后需的fgets没有值]]sprintf(cmd,"awk '{print $1,\"popen\"}' popen.txt > temp_1 && mv -f temp_1 popen.txt && cat popen.txt");printf("%s\n",cmd);fp = popen(cmd,"r");if(NULL == fp){ printf("asda\n");return 1;}while(NULL != fgets(line,sizeof(line),fp)) {printf("line[%d] = %s",j,line); j++;}pclose(fp);return 0; } //结果显示如下::: line[1] = asdfgh popen.txt line[2] = qwerty popen.c awk '{print $1,"popen"}' popen.txt > temp_1 && mv -f temp_1 popen.txt && cat popen.txt line[1] = asdfgh popen line[2] = qwerty popen

awk的其他的使用请看【Linux命令之 —— grep \ls \ ll \ sed \ bg fg \ ipset \ wc \ ifconfig \ awk】
参考链接:https://www.cnblogs.com/52php/p/5722238.html

总结

以上是生活随笔为你收集整理的函数 —— popen() fscanf() sprintf() 执行shell命令并获取结果的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。