1.25 实现一个终端的功能

实现一个终端的功能,包含cd的功能。

cs 复制代码
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;

// 自定义的 fgets 函数,去除换行符
char* mygets(char* s, int size) {
    char* res = fgets(s, size, stdin);
    int len = strlen(s);
    if (s[len - 1] == '\n') {
        s[len - 1] = '\0';
    }
    return s;
}

int main(int argc, const char *argv[]) {
    while (1) {
        // 获取用户名
        char* username = getlogin();
        // 获取主机名
        char hostname[64] = {0};
        gethostname(hostname, 63);
        // 获取当前路径
        char cwd[1024] = "";
        getcwd(cwd, sizeof(cwd) - 1);

        // 打印命令提示符
        printf("\033[1;32;10m%s@%s\033[0m:\033[1;34;10m%s\033[0m$ ", username, hostname, cwd);
        fflush(stdout);

        // 读取用户输入的命令
        char shell[256] = {0};
        char* cmd[100] = {0};
        mygets(shell, 256);

        // 解析命令
        char* res = NULL;
        int i = 0;
        while (1) {
            if (res == NULL) {
                res = strtok(shell, " ");
            } else {
                res = strtok(NULL, " ");
            }

            if (res == NULL) {
                break;
            }
            cmd[i] = res;
            i++;
        }

        // 检查是否为 cd 命令
        if (cmd[0] != NULL && strcmp(cmd[0], "cd") == 0) {
            if (cmd[1] == NULL) {
                // 如果没有提供参数,默认切换到用户主目录
                const char* home = getenv("HOME");
                if (home == NULL) {
                    fprintf(stderr, "cd: 无法获取主目录\n");
                } else {
                    if (chdir(home) != 0) {
                        perror("cd");
                    }
                }
            } else {
                // 切换到指定目录
                if (chdir(cmd[1]) != 0) {
                    perror("cd");
                }
            }
            continue;
        }

        // 执行其他命令
        pid_t pid = fork();
        if (pid > 0) {
            wait(0);
        } else if (pid == 0) {
            if (execvp(cmd[0], cmd) == -1) {
                printf("%s: 未找到命令\n", cmd[0]);
                exit(EXIT_FAILURE);
            }
        } else {
            perror("fork");
        }
    }
    return 0;
}
相关推荐
C4程序员3 分钟前
Java百度身份证识别接口实现【配置即用】
java·开发语言
unityのkiven13 分钟前
C++中的虚表和虚表指针的原理和示例
开发语言·c++
炒空心菜菜17 分钟前
MapReduce 实现 WordCount
java·开发语言·ide·后端·spark·eclipse·mapreduce
(・Д・)ノ19 分钟前
python打卡day27
开发语言·python
小疆智控30 分钟前
数字化工厂升级引擎:Modbus TCP转Profinet网关助力打造柔性生产系统
服务器·网络·tcp/ip
芯眼42 分钟前
STM32启动文件详解(重点)
java·开发语言·c++·stm32·单片机·mybatis
xiao--xin1 小时前
计算机网络笔记(二十七)——4.9多协议标签交换MPLS
网络·笔记·计算机网络·mpls
愚润求学1 小时前
【Linux】动静态库链接原理
linux·运维·服务器·开发语言·笔记
呦呦彬1 小时前
【问题排查】easyexcel日志打印Empty row!
java·开发语言·log4j
Tummer83631 小时前
C#+WPF+prism+materialdesign创建工具主界面框架
开发语言·c#·wpf