1,重定向
重定向是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作,操作句柄为文件描述符,可以将文件描述符想象成两个指针,相当于指针所指的内容变了。
stdin(标准输入) 0 从键盘获得输入
stdout(标准输出) 1 输出到屏幕
stderr(标准错误) 2 输出到屏幕
常用到的两个输出重定向的符号">" 和 “>>”
第一个是清空重定向,会先清空文件的原有内容再向其中添加内容。
第二个属于追加重定向,直接在文件原有内容的末尾追加内容。
minishell实现流程:
获取标准输入->命令字符串解析(命令程序名称+程序运行参数)->创建子进程->子进程进行程序替换,完成用户需要功能
->父进程进行进程等待,等待子进程退出,避免僵尸进程。
先构建一个mikefile文件
模拟实现shell代码如下
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
while(1){
printf("[wbc@localhost]$ ");
fflush(stdout); //刷新缓冲区,stdout标准输出,可以显示出来否则一直有个\n,无法进行输出
char buf[1024] = {0};//字符数组,存放用户输入
//%[^\n]:从缓冲区读取字符串遇到\n停下,%*c:从缓冲区取一个字符,scanf()成功则返回值为1,失败为0
if(scanf("%[^\n]%*c",buf) != 1){
getchar(); //把\n放到getchar()中
continue;
}
char* argv[32]; //指针数组来存储每个有效字符串首地址
int argc = 0;
char* ptr = buf; //创建一个指针指向buf字符数组
while(*ptr!='\0'){ //只要没到输入的字符串末尾就继续往下走
if(!isspace(*ptr)){ //isspace函数判断是否空格,是的话就返回真
argv[argc++] = ptr; //走到不是空格的地方就存下这个位置
//然后把这个字符走完,之后在末尾添上'\0'
while(*ptr!='\0' && !isspace(*ptr)){
ptr++;
}
}
*ptr = '\0';
ptr++; //继续往后走判断
}
argv[argc] = NULL; //走完整个字符串后就在末尾加上NULL
if(strcmp(argv[0],"cd")==0){//判断是否是内建命令,是的话,就直接执行,否则改变路径
chdir(argv[1]);
continue;
}
int pid = fork();
if(pid<0){ //创建子进程失败,则继续创建,因为用户还要输入指令
printf("fork error!");
continue;
}
else if(pid==0){//创建子进程来完成程序替换任务
if(execvp(argv[0],argv)<0){//返回值<0则说明有错,否则就直接执行替换的程序
perror("");
}
exit(0);//如果有错那就退出
}
//等待子进程退出,否则子进程会成为僵尸进程
wait(NULL);
}
return 0;
}