MiniShell은 Bash 쉘의 다양한 기능을 C 언어로 구현한 쉘 프로그램입니다.
이 프로그램은 사용자가 입력한 명령어를 해석하여,
명령어를 실행하고, 프로세스 생성, 시그널 처리, 환경 변수 관리 등
다양한 기능을 제공합니다.
minishell_.mov
- 프로젝트 root에서
./init.sh
실행 ./minishell
실행- 종료하고 싶으면
exit
명령어 입력
-
명령어 파싱: 사용자가 입력한 명령어를 공백과 여러 키워드 기준으로 토큰화하고, 어휘 분석을 통해 syntax error를 검사합니다. 이후 parsing에서 구조체에 적절하게 담아 리턴합니다. 이 과정에서 따옴표 제거와 환경변수 확장 같은 문자열 확장을 처리합니다.
-
환경변수 관리: 환경 변수의 설정 및 조회 기능을 지원합니다.
export
혹은env
명령어를 사용하여 새로운 환경 변수를 추가하거나 기존 변수를 업데이트할 수 있습니다. 환경변수 리스트는 자식 프로세스에도 전달되어 자식 프로세스에서 부모의 환경변수에 접근할 수 있습니다. -
명령어 실행: 외부 프로그램의 경우 fork()로 새로운 프로세스를 생성하고 execve()를 통해 실행합니다. 부모 프로세스는 waitpid()를 통해 자식 프로세스가 종료되면 이를 정리합니다. 쉘 자체에서 실행되어야 하는 builtin 명령어들은 시스템 콜을 통해 구현하였습니다.
-
파이프라인 처리: 파이프를 지원하여 각 프로세스의 출력이 다른 프로세스의 입력으로 사용되도록 파이프라인을 구성하였습니다. 이를 위해
pipe()
와fork()
를 사용하여 각 명령어가 별도의 자식 프로세스에서 실행되도록 구현하였습니다. 이를 통해 각 프로세스가 병렬적으로 처리되며, 표준 입출력을 파이프로 리다이렉션 시켜 프로세스간의 통신을 구현하였습니다. -
리다이렉션 처리: 명령어의 입력과 출력을 파일로 리다이렉트하는 기능을 지원합니다.
<
,>
,<<
,>>
연산자를 사용하여 입력 리다이렉션과 출력 리다이렉션을 구현하였으며,open()
과dup2()
시스템 호출을 통해 표준 입력 및 출력을 파일로 연결합니다.<<
와 같이 heredoc 기능을 구현하여, 명령어의 입력을 여러 줄로 받을 수 있습니다. EOF 식별자가 나오거나 인터럽트 시그널을 받을 때까지의 입력을 명령어에 전달합니다. 이를 통해 스크립트나 파일 입력 없이도 복잡한 명령어 입력이 가능합니다. -
시그널 처리:
SIGINT
,SIGQUIT
등 주요 시그널에 대한 핸들러를 설정하여, 쉘 프로세스와 자식 프로세스가 시그널에 대해 다르게 처리할 수 있도록 하였습니다. 쉘 프로세스는 시그널을 받더라도 종료되지 않고 실행을 지속할 수 있게 하였습니다. -
종료 코드 확인: 쉘에서 마지막으로 실행된 명령어의 종료 코드를
$?
로 확인할 수 있는 기능을 구현하였습니다. 명령어 실행 후 반환된 종료 상태 코드를 저장하고, 이를$?
를 통해 사용자에게 제공하여, 스크립트 작성 시 오류 처리가 가능하도록 하였습니다.