天天看點

C語言模拟終端執行shell指令

程式隻支援ls、cat和ps三個指令,思路是在使用者輸入一條指令之後fork一個新的程序,在新的程序裡面執行指令。

在我了解中,Mac的終端思路應該是類似的。在打開終端之後,程式會讀取配置檔案中目錄下可執行的指令,然後根據使用者的指令判斷指令是否存在,如果存在,則fork出一個新的程序執行,否則傳回“command not found”。

本來覺得代碼不複雜,但是寫了很長時間,主要是兩個問題,一個是strtok函數一直有問題,整了好長時間都沒搞明白該怎麼處理,最後沒辦法自己實作了一個非常簡陋的字元串截取函數(隻支援按照單個空格截取);另一個是指針的處理,我對C語言的指針一直不太熟悉,遇上稍微複雜的一些情況就不知道該怎麼弄,折騰了很久。

寫完之後我在想應該不需要fork一個新的程序,直接執行指令好像就行了。

不過沒關系,我想寫一個簡單的web伺服器,就當是練手了。

程式執行結果:

C語言模拟終端執行shell指令

上代碼:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
int split(char *s,char *delim[])
{
	int j=0;
	int k=0;
	char temp[100];
	for(int i=0;s[i]!='\0';i++)
	{
		if(s[i]!=' ')
		{
			temp[j++]=s[i];
		}else
		{
			temp[j]='\0';
			delim[k] = (char *)malloc(strlen(temp));
			strcpy(delim[k],temp);
			j=0;
			k++;
		}
	}
	temp[j]='\0';
	delim[k] = (char *)malloc(strlen(temp));
	strcpy(delim[k],temp);
	k++;
	return k;
}
int main()
{
	char *commands[] = {"/bin/ls","/bin/cat","/bin/ps"};
	int parent_pid = getpid();
	while(1)
	{
		printf("Please input your command: ");
		char *command;
		fgets(command,100,stdin);
		command[strlen(command)-1]='\0';
		fork();
		int pid = getpid();
		if(pid==parent_pid)
		{
			wait(NULL);
			continue;
		}else
		{
			int flag = 0;
			char *argv[5];
			int k = split(command,argv);
			argv[k]=NULL;
			for(int i=0;i<3;i++)
			{
				if(strstr(commands[i],argv[0]))
				{
					flag=1;
					char *envp[] = {NULL};
					execve(commands[i],argv,envp);
					break;	
				}
			}
			if(!flag)
			{
				printf("command not found: %s\n",argv[0]);
			}
			break;	
		}
	}
	return 0;
}
           

繼續閱讀