Linux:简易Shell

文章目录


全文约 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

  1. 获取命令行
  2. 解析命令行
  3. 建立一个子进程(fork)
  4. 替换子进程(execvp)
  5. 父进程等待子进程退出(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教程
    - 拆开都懂,放一块儿我仿佛就是个韩寒
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值