全文约 1516 字,预计阅读时长: 6分钟
前言
- C 库函数
char *fgets(char *str, int n, FILE *stream)
从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。- 当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
- 如果成功,该函数返回相同的 str 参数。
- 如果到达文件末尾或者没有读取到任何字符,str 的内容保持不变,并返回一个空指针。如果发生错误,返回一个空指针。
- C 库函数
char *strtok(char *str, const char *delim)
分解字符串 str 为一组字符串,delim 为分隔符。- delim – 包含分隔符的 C 字符串。
- 该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。
- 会自动处理多个相同分割字符串的情况。
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while( token != NULL ) {
printf( "%s\n", token );
token = strtok(NULL, s);
}
-
chdir函数:
int chdir(const char *path);
- 参数:path可以是绝对目录或者相对目录
- 功能:改变当前工作目录
- 返回值:成功返回0,失败返回-1
-
命令提示符那一栏可以通过相关函数获得。
Shell
- 获取命令行
- 解析命令行
- 建立一个子进程(fork)
- 替换子进程(execvp)
- 父进程等待子进程退出(waitpid)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#define NUM 128
#define SIZE 32
char command_line[NUM];
char *command_parse[SIZE];
int main()
{
while(1){
memset(command_line, '\0', sizeof(command_line));
printf("[whb@myhost 我的shell]$ ");
fflush(stdout);
//1. 数据读取
if(fgets(command_line, NUM-1, stdin)){
command_line[strlen(command_line) - 1] = '\0';
//ls -a -l -i
//2. 字符串(命令行数据分析)
int index = 0;
command_parse[index] = strtok(command_line, " ");
while(1){
index++;
command_parse[index] = strtok(NULL, " ");
if(command_parse[index] == NULL){
break;
}
}
//3. 判断命令 //a. 内置命令 //b. 第三方命令
if(strcmp(command_parse[0], "cd") == 0 && chdir(command_parse[1]) == 0){
continue;
}
// 执行非内置命令
if(fork() == 0){
//子进程
execvp(command_parse[0], command_parse); // ls ls -a -i -l
exit(1);
}
int status = 0;
pid_t ret = waitpid(-1, &status, 0);
if(ret > 0 && WIFEXITED(status)){
printf("Exit Code: %d\n", WEXITSTATUS(status));
}
}
}
return 0;
}
参考
- C教程
- 拆开都懂,放一块儿我仿佛就是个韩寒