Shell到底是什麼?
1.shell的含義:
shell這個單詞的英文含義爲“殼”。顧名思義,Shell就像是一個外殼一樣。就我理解而言,Shell本身是一段程序,它運行起來後,可以和內核來打交道。它是相對於內核來說的,建立在內核的基礎上,面向於用戶的一種表現形式。就好比我們看到一個球體,見到的只是外殼,並非內核。
Linux中的shell,是指一個面向用戶的命令接口,表現形式就是一個可以由用戶錄入的界面,這個界面也可以反饋運行信息。
我用下圖來表示時間的流逝(從左到右)以及事件發生的次序。shell從用戶讀入字符串“ls”,shell建立一個新的進程,然後在那個進程中運行ls程序並等待那個進程結束。然後shell又讀取新的一行,建立新的進程,做同上的工作。
綜上,我們可以總結出來,要實現一個迷你shell,必須循環以下步驟:
(1)獲取命令行
(2)解析命令行
(3)建立一個子進程(fork())
(4)替換子進程(execvp())
(5)父進程等待子進程退出(wait())
具體代碼如下:
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* argv[8];
int argc = 0;
void do_parse(char* buf)
{
int i;
int status = 0 ;
for(argc = i = 0; buf[i]; i++)
{
if(!isspace(buf[i]) && status == 0)
{
argv[argc] = buf+i;
argc++;
status = 1;
}
else if(isspace(buf[i]))
{
status = 0;
buf[i] = 0;
}
}
argv[argc] = NULL;
}
void do_execute(void)
{
pid_t pid = fork();
switch(pid)
{
case -1:
perror("fork");
exit(EXIT_FAILURE);
break;
case 0:
execvp(argv[0], argv);
perror("execvp");
exit(EXIT_FAILURE);
default:
{
int st;
while(wait(&st) != pid)
;
}
}
}
int main()
{
char buf[1024] = {};
while(1)
{
printf("MyShell> ");
scanf("%[^\n]%*c", buf);
do_parse(buf);
do_execute();
}
return 0;
}
運行結果: