随着自己接触越来越多的linux的系统函数发现自己在linux系统调用方面有很多不足,每次遇到系统调用函数都要百度一遍看一下用法,所以我打算写一篇博客来记录在开发过程遇到的系统调用函数,方便自己查阅。本文持续更新
1、popen()函数
2、fgets()函数
3、system()函数
4、strstr()函数
1、popen()
这是一个与管道有关的系统调用,在我最早的一篇文章里有写过关于管道的理解"管道就像一条水管,从一头流到另外一头,不会阻塞"。具体可以参考https://blog.csdn.net/tiramisu_L/article/details/80176350
popen()函数创建一个管道,然后会自动创建子进程来执行shell,shell会创建一个子进程来执行command字符串。mode只有两种状态:读数据(r), 写数据(w)。这里需要注意一下,这里创建子进程是系统自己完成的,不需要用户调用fork()来创建子进程。
使用完之后需要用pclose()来关闭这个管道。
其实用最通俗的理解,这个函数跟system()函数是一样的,就是执行一条shell指令(command字符串)。只是他通过管道的方式,可以读取或者写入一些数据。
一个例子:
本例中doc.txt文件的数据是一些简单的无意义的字符,内容如下
#include
#include
#include
int main()
{
FILE *fp;
char buf[512];
char cmd[] = "cat /mnt/hgfs/work/test/doc.txt";
fp = popen(cmd,"r");
while (fgets(buf,sizeof(buf),fp) != NULL)
{
printf("len=%ld ",strlen(buf));
printf("%s",buf);
}
return 0;
}
运行之后可以看到结果如上
其实就是在Ubuntu的终端执行cat命令去查看目标文件的内容,当然你可以换成ls等等命令也是可以的。注意上面说的,这里我是没有手动建立子进程的,因为系统会自动帮我们建立好子进程。
有人会问这有什么意义?直接用system()不是更方便吗?有时候我们执行完一些指令或者一些脚本的时候会输出一些信息,我们需要筛选这些输出信息的某些关键信息来做后续处理,popen()的好处就在这里。
假设我需要筛选出677这个数据,并在筛选出之后结束我的程序, 上面的程序可以做以下更改
#include
#include
#include
int main()
{
char *ret;
FILE *fp;
char buf[512];
char cmd[] = "cat /mnt/hgfs/work/test/doc.txt";
fp = popen(cmd,"r");
while (fgets(buf,sizeof(buf),fp) != NULL)
{
printf("len=%ld ",strlen(buf));
printf("%s",buf);
ret = strstr(buf,"677");
if (ret != NULL)
{
printf("ret=%s\n",ret);
break;
}
}
return 0;
}
可以看到,在检测到677之后我的程序提前结束了,这就是popen()函数的好处,可以用来筛选。
上面讲到fgets()和strstr()还有system()函数,接下来会慢慢写。
2、fgets()
fgets()函数相对就很简单。先来看一下他的定义
这个函数就是用来操作字符串的。是从一个文件流中获取字符串,注意只是字符串。有一个地方需要注意的,fgets()函数会读入换行符'\n',并且在读入换行符之后立刻返回,换行符之后的字符串不会被读取。
读者可以注意到前面讲popen()函数的时候在用fgets()函数读取字符串的时候,我使用了while(),原因就是为了可以连续读取完所有的字符串,我们可以来试一下,如果不用while()结果会是怎么样。
#include
#include
#include
int main()
{
char *ret;
FILE *fp;
char buf[512];
char cmd[] = "cat /mnt/hgfs/work/test/doc.txt";
fp = popen(cmd,"r");
if (fgets(buf,sizeof(buf),fp) != NULL)
{
printf("len=%ld ",strlen(buf));
printf("%s",buf);
ret = strstr(buf,"677");
if (ret != NULL)
{
printf("ret=%s\n",ret);
//break;
}
}
return 0;
}
从结果可以看到,没有while循环之后,只会打印第一行字符串,在遇到换行之后函数立刻返回了。
3、strstr()
这个函数其实也很简单。先看一下定义(我在电子书很纸质文档没有找到这个函数的定义,只能man一下这个函数了)
这个函数其实是用来定位查找需要的字符的(没错,又是用来操作字符串的函数)。就是在haystack这个字符串中找到第一次出现的needle字符串,找到之后返回目标字符串的地址。
举个简单的例子:
#include
#include
#include
int main()
{
char *ret;
char buf[] = "hhfahlkakWilliamakdajWilliam12345";
ret = strstr(buf,"William");
printf("str=%s\n",ret);
return 0;
}
从结果可以看到,strstr函数在遇到第一个Willam的时候就会返回,并且是返回这个字符串的地址。所以打印的时候把第一次出现的William以及后面的字符都打印出来了
4、system()
这个函数其实就是执行一条shell指令。用vs写过C++的同学一定知道在写完C++程序return之前一般都会加一句system("pause")。其实这个作用就是把窗口暂停一下,方便你观看。 看一下这个函数的声明
话不多说,直接上一个简单的例子
#include
#include
int main()
{
char command[] = "ls";
system(command);
return 0;
}
这个例子主要就是看一下我当前路径的文件夹下有什么内容,其实相当于我在Ubuntu上执行一遍ls这个shell命令。
原创不易,转载请注明出处!