소개글
숭실대학교 첫번째 과제. 50점 만점 중 45점 받은 과제입니다.3.2 쉘 구현
3.2.1 명령어 실행(fork, exec):
- fork와 exec 관련 시스템콜을 사용하여 프로세스를 생성하고 해당 명령어를 수행한다. 명령어의 옵션도 수행되게 한다.
- 외부명령어를 실행할 경우 환경변수의 PATH 경로를 참조하여 수행하고 명령어가 존재하지 않을시 오류 메시지를 출력한다.
ex) ls 의 사용과 명령어 옵션의 사용, 오류 메시지 출력
# ls
....
# ls -al (옵션도 사용이 가능해야 함)
....
# asd
asd : command not found (존재하지 않는 명령어일 경우)
#
3.2.2 히스토리(history):
- 명령 실행시 .history 파일을 만들고 저장한다.
- 쉘 실행시 .history 파일에서 이전에 실행했던 히스토리 명령을 불러온다.
- history 를 입력하면, 히스토리 목록을 출력한다. !number는 히스토리 목록 내에서 해당 번호에 해당하는 명령 라인을 수행한다.
- !!는 이전에 실행했던 명령을 수행한다.
ex) 히스토리 목록
# history
1 vi test.c
2 ls
3 ls -al
4 clear
#
!3 를 입력하면, 히스토리 목록 내의 3번에 해당하는 ls -al 을 수행한다.
!! 를 입력하면, 목록내에 마지막에 등록되있는 clear 을 수행한다.
히스토리에 대한 관련 링크 :
http://www.gnu.org/software/bash/manual/bashref.html#Using-History-Interactively
3.2.3 환경변수 설정: export 환경 변수 등록
- envprint 라는 명령으로 등록한 환경 변수와 그에 해당하는 값을 모두 출력할 수 있게 한다.
반드시 본인이 만든것으로 이용하도록 한다.
- 기본적으로 저장되어 있어야 하는 환경변수
- PATH="/bin"
- PS="본인의학번# "
ex) HOSTNAME 등록, envprint 명령으로 환경변수 값들의 출력
# export HOSTNAME=com ( HOSTNAME 이라는 환경 변수의 값은 SSU 이다. )
# envprint
HOSTNAME="com"
PATH="/bin"
PS="본인의학번# "
#
* PATH의 경우 ;(세미콜론)을 이용한 복수 PATH 적용부분은 구현하지 않아도 됩니다.
환경변수에 대한 관련 링크 :
http://www.gnu.org/software/bash/manual/bashref.html#Environment,
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html
3.2.4 리다이렉션(redirection): 가장 간단한 버전으로 구현
- a 는 명령어 혹은 명령어와 옵션, b는 파일을 나타낸다.
# a > b (a 명령의 출력값을 b에 저장한다. )
# a < b (a명령를 수행하기 위해 필요한 입력 값을 b에서 얻는다. )
# a >> b (a 명령의 출력값을 b에 추가(append)한다. )
ex) 현재 폴더의 내용을 a.txt 에 저장
# ls -al > a.txt
#
리다이렉션에 대한 관련 링크 :
http://www.gnu.org/software/bash/manual/bashref.html#Redirections
3.2.5 파이프: 가장 간단한 버전으로 구현
- a의 출력을 b의 입력으로 한다.
# a | b
ex) 현재 폴더의 내용을 grep 으로 필터링
# ls -al | grep 1
#
ex) history 목록에서 원하는 부분만 grep 으로 필터링
# history | grep ls
#
파이프에 대한 관련 링크 :
http://www.gnu.org/software/bash/manual/bashref.html#Pipelines
3.2.6 exit
- exit 는 현재 쉘을 종료하는 명령이다.
ex) 현재 쉘을 종료
# exit
exit에 대한 관련 링크 :
http://www.gnu.org/software/bash/manual/bashref.html#Exit-Status
3.2.7 프롬프트 변경
- 환경변수 PS의 값을 바꿔서 프롬프트를 바꿀 수 있다.
- 환경변수 값의 종류는 다음 네가지만 구현한다.
* H : 현재 호스트 이름을 출력
* t : HH:MM:SS 형식으로 24시간제 시간을 출력
* u : 현재 사용자 id 출력
* w : 현재 디렉토리 전체 경로 출력
* 문자 : 문자가 그대로 출력
ex) 호스트 이름이 com 이고 사용자 이름이 1234 인 경우
# envprint
HOSTNAME = "com"
USERNAME = "1234"
# export PS="test ::# "
test ::# ¶
test ::# export PS="H# "
com# ¶
com# export PS="t# "
14:35:19# ¶
14:35:19# export PS="u# "
1234# ¶
1234# export PS="w# "
/home/sr/test# ¶
/home/sr/test# export PS="u@h w$ "
1234@com /home/sr/test$ _
프롬프트 변경에 대한 관련 링크 :
http://www.gnu.org/software/bash/manual/bashref.html#Printing-a-Prompt
3.2.8 백그라운드(background)
- '&' 를 사용하여 명령어를 백그라운드로 실행 할 수 있게 한다.
ex) a 명령어를 백그라운드로 처리한다.
# a &
#
3.2.9 복합기능 수행 가능
- 위에 기술된 모든 기능이 복합적으로 수행이 가능해야 한다.
ex) history 목록을 grep 으로 필터링한 목록들을 1.txt로 리다이렉션
# history | grep 1 > 1.txt
#
마지막으로 bash 쉘에 대한 다양한 도움말을 얻을 수 있는 사이트들이다.
1. Bash Reference Manual http://www.gnu.org/software/bash/manual/bashref.html
2. Bash Guide for Beginners http://tldp.org/LDP/Bash-Beginners-Guide/html/
3. Advanced Bash Scripting Guide http://tldp.org/LDP/abs/html/index.html
컴파일 실행환경
없음본문내용
#include "myshell.h"void prompt()
{
account = getpwnam(getlogin());
getcwd(path,512);
printf("[%s@song shell%s] # ",account->pw_name,path);
}
void inputCommand(char *command)
{
int i;
int temp=1;
strcpy(before_command, command);
for(i= 0 ; (*(command+(i-1)) != '\n' ) ; i++)
{
*(command + i) = getchar();
if(*(command+i)=='|')
temp=0;
history_list[0][i]=*(command+i);
}
history_list[0][i-1] = '\0';
history_list[0][i] = '\0';
*(command + (i-1)) = '\0';
*(command + (i)) = '\0';
argc = i;
if(temp==0)
{
pipe_job(command);
}
if(his_save==1)
{
//if(fopen("history", "w")!=null);
file = fopen("history","w");
if(file==NULL)
{
file=fopen("history","wt");
}
fprintf(file, "%d %s\n",his_save, history_list[0]);
}
else
{
file = fopen("history", "a+");
fprintf(file, "%d %s\n",his_save, history_list[0]);
}
fclose(file);
}
int executeJob(char *command)
{
char ch;
char *shArgv[30];
char **env;
char temp[50];
char com_temp[128];
int index=0;
int pid, i;
int amper = 0;
int ppid;
int status;
if(distinct==1){
distinct = 0;
}
strcpy(command_copy,command);
if(strpbrk(command, "&"))
{
amper = 1;
}
else if(strstr(command, ">>"))
{
redirection_job(command_copy, 1);
return 1;
}
else if(strstr(command, ">"))
{
redirection_job(command_copy, 2);
return 1;
}
else if(strstr(command, "<"))
{
redirection_job(command_copy, 3);
return 1;f
}
shArgv[0] = strtok(command," \n");
if(shArgv[0] == NULL)
return 1;
while(shArgv[index])