一、命令行信息提示格式
xshell的命令行
持续等待输入
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#define NUM 128 //指令长度
int main()
{
char commond[NUM];//指令
while(1)
{
//清空字符串
commond[0] = 0;
printf("[Rinne@windows 11 xsehll]# ");
fflush(stdout);//标准输出进行刷新
sleep(1);
}
return 0;
}
二、获取指令
根据之前所学,指令可以拿数组存放
scanf不行,因有空格会停下
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#define NUM 128 //指令长度
int main()
{
char command[NUM];//指令
while(1)
{
//清空字符串
command[0] = 0;
printf("[Rinne@windows 11 xsehll]# ");
fflush(stdout);//标准输出进行刷新
fgets(command, NUM, stdin);
printf("echo: %s\n", command);
}
return 0;
}
如果输入错误ctrl + delete删除
这里发现多了一个\n是我们输入的时候回车时候的那个\n
while(1)
{
//清空字符串
command[0] = 0;
printf("[Rinne@windows 11 xsehll]# ");
fflush(stdout);//标准输出进行刷新
fgets(command, NUM, stdin);
command[]
printf("echo: %s\n", command);
}
三、分割指令
使用strtok函数
第一次调用strtok函数时,传递原始字符串以及分解字符串
之后再调用strtok函数时,只需要传递NULL和分解字符串
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#define SZ 64
#define NUM 128 //指令长度
int main()
{
char command[NUM];//指令
while(1)
{
char* argv[SZ] = {NULL};
//清空字符串
command[0] = 0;
printf("[Rinne@windows 11 xsehll]# ");
fflush(stdout);//标准输出进行刷新
fgets(command, NUM, stdin);
command[strlen(command) - 1] = 0;
const char* seek = " ";
argv[0] = strtok(command, seek);
int i = 1;
while(argv[i] = strtok(NULL, seek))
{
i++;
}
//check
for(size_t j = 0; argv[j]; j++)
{
printf("%s\n", argv[j]);
}
}
return 0;
}
四、创建子进程进行程序替换(执行命令行)
xshell的命令的传参方式和execvp很像
ls -l -a -d
//文件名 //如何执行,指令字符串
int execlp(const char *file, const char *arg, ...);
argv[0]是个字符串,程序本身的文件名。比如ls -a,ls存在argv[0]是文件名
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#define SZ 64
#define NUM 128 //指令长度
int main()
{
char command[NUM];//指令
while(1)
{
char* argv[SZ] = {NULL};
//清空字符串
command[0] = 0;
printf("[Rinne@windows 11 xsehll]# ");
fflush(stdout);//标准输出进行刷新
fgets(command, NUM, stdin);
command[strlen(command) - 1] = 0;
const char* seek = " ";
argv[0] = strtok(command, seek);
int i = 1;
while(argv[i] = strtok(NULL, seek))
{
i++;
}
//check
/*for(size_t j = 0; argv[j]; j++)
{
printf("%s\n", argv[j]);
}*/
if(fork()==0)
{
execvp(argv[0], argv);
exit(1);
}
waitpid(-1, NULL, 0);
}
return 0;
}
但这是简陋的xshell,| 、 > 都不认识
五、创建内建命令
这里进行多次cd,目录都没有改变
总结:凡是usr/bin/目录下的指令都是创建子进程进行的
如果要内建命令方式,改变父进程:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#define SZ 64
#define NUM 128 //指令长度
int main()
{
char command[NUM];//指令
while(1)
{
char* argv[SZ] = {NULL};
//清空字符串
command[0] = 0;
printf("[Rinne@windows 11 xsehll]# ");
fflush(stdout);//标准输出进行刷新
fgets(command, NUM, stdin);
command[strlen(command) - 1] = 0;
const char* seek = " ";
argv[0] = strtok(command, seek);
int i = 1;
while(argv[i] = strtok(NULL, seek))
{
i++;
}
//check
/*for(size_t j = 0; argv[j]; j++)
{
printf("%s\n", argv[j]);
}*/
if(strcmp(argv[0], "cd") == 0)
{
if(argv[1] != NULL)
{
chdir(argv[1]);
continue;
}
}
if(fork()==0)
{
execvp(argv[0], argv);
exit(1);
}
waitpid(-1, NULL, 0);
}
return 0;
}