Linux:基础IO
- 对之前编写的自主shell进行修改,使其支持输入/输出/追加重定向
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
//1.写一个shell的入口,用于提示要输入信息
//2.scanf接受一个输入信息
//对命令进行解析,看看有没有进行重定向
//3.创建子进程
//4.程序替换
int main()
{
while(1){
printf("minishell:");
fflush(stdout);
char cmd[1024]={0};
if(scanf("%[^\n]%*c",cmd)!=1){//按回车依然死循环,ls不会死循环
getchar();
//%[^\n]表示的是获取数据直到遇到\n为止。
//%*c:将缓冲区中的字符都取出来,但是不要它,直接丢掉,目的是为了将最后的\n从缓冲区中取出来防止陷入死循环。
}
//将获取的命令解析一下,判断是否有输出重定向
//
char *ptr=cmd;
int is_redirect=0;
char *redirect_file=NULL;
while(*ptr!='\0')
{
if(*ptr=='>')
{
is_redirect++;
*ptr++='\0';
if(*ptr=='>')
{
is_redirect++;
*ptr++='\0';
}
while(isspace(*ptr)&&*ptr!='\0')
{
ptr++;
}
redirect_file=ptr;
}
ptr++;
}
int fd;
if(is_redirect==1)
{
fd=open(redirect_file,O_WRONLY|O_CREAT|O_TRUNC,0777);
if(fd<0)
{
return -1;
}
}
else if(is_redirect==2)
{
fd=open(redirect_file,O_WRONLY|O_CREAT|O_APPEND,0777);
if(fd<0)
{
return -1;
}
}
//将获取到的命令解析一下,然后创建子进程进行程序替换。
ptr=cmd;
char *argv[32]={NULL};
int argc=0;
argv[argc++]=ptr;
while(*ptr!='\0'){
//ls -l
if(isspace(*ptr)){
//用于判断一个字符是否是:\t \n \r
//解析一个字符串的时候这里就是对空格的判断
while(isspace(*ptr)&&&ptr!='\0'){
*ptr++='\0';
}
if(*ptr=='\0')
break;
argv[argc++]=ptr;
}
ptr++;
}
//printf("%s\n",cmd);
if(fork()==0){
if(is_redirect)
{
dup2(fd,1);
}
execvp(argv[0],argv);
}
//1.不等待就会有僵尸进程
//2.是为了等待子进程运行完毕,让程序逻辑更加完善。
wait(NULL);
}
return 0;
}
测试:
vim a.txt
我们可以看到:ls的内容都内写入到a.txt中。
- 编写简单的add/sub/mul/div函数,并打包成动/静态库,并分别使用
静态库:
1.先编写四个函数相关头文件.h和.c文件
格式如下:
2.用gcc -c add.c sub.c mul.c div.c生成-o文件
3.编译生成静态库
ar -rc libmath.a add.o sub.o mul.o div.o
4.编写一个test.c文件
5.编译,运行。
gcc -o test test.c -L. -lmath //-L静态库的位置 -l那个库
./test
动态库:
1.先mkdir dongtaiku
cd dongtaiku
2.将实现静态库的四个.h和test.c函数拷贝到当前目录下
3.生成动态库
用gcc -c add.c sub.c mul.c div.c生成-o文件
再gcc -share -o libmath.so *.o //*.o代表所有的.o文件
4.生成可执行程序
gcc -o test test.c -L. -lmath
5.改变系统查找动态库的路径
export LD_LIBRARY_PATH=. //查找动态库的路径设置到当前路径下\
如果不设置,会报错,没有设置系统找不到动态库的路径
6.运行./test