minishell
파일 입출력, 멀티 프로세스, 시그널 심화
제한된 기능의 bash shell을 C로 구현하는 과제이다. 사용자가 명령어를 입력하면 이를 파싱하고, 프로세스를 생성하여 실행하고, 결과를 출력하는 셸의 전체 동작 흐름을 직접 구현한다.
- 개발 기간: 2024.01 ~ 2024.03
- 과정: 42 Seoul Inner Circle
- 언어: C
- GitHub: https://github.com/Budnarae/42_innercircle_course/tree/main/minishell
- 팀 멤버:
- 담당 역할: 사용자의 Shell Script 입력을 파싱하는 로직 구현
개요
셸은 사용자가 입력한 텍스트를 해석하여 운영체제에 전달하는 인터페이스다. minishell은 bash의 핵심 동작을 구현하며, 입력된 명령줄을 토큰으로 분리하는 파싱 단계부터 실제 프로세스를 생성하여 실행하는 단계까지 전 과정을 다룬다.
실행 파일은 readline 라이브러리에 의존성을 가지므로 아래 명령어를 먼저 실행해야 한다.
sudo apt-get install libreadline-dev구현 내용
토큰화 및 구문 분석
사용자가 입력한 문자열을 의미 단위(토큰)로 분리하고, 쌍따옴표/따옴표 내부의 처리, 파이프와 리다이렉션 연산자의 위치 등을 파악하여 실행 가능한 구조로 변환한다. 괄호를 사용한 명령어 그룹핑과 &&, || 논리 연산자도 파싱한다.
프로세스 생성 및 명령 실행
파싱 결과를 바탕으로 fork로 자식 프로세스를 생성하고, execve로 실제 프로그램을 실행하며, wait으로 자식 프로세스의 종료를 기다린다.
파이프라인 및 리다이렉션
아래 연산자들을 처리한다. 파이프는 앞 명령어의 표준 출력을 뒤 명령어의 표준 입력으로 연결하며, 리다이렉션은 파일 디스크립터를 파일로 연결한다.
| 연산자 | 동작 |
|---|---|
| | 파이프: 앞 명령의 출력을 뒤 명령의 입력으로 연결 |
< | 표준 입력을 파일에서 읽음 |
> | 표준 출력을 파일에 씀 (덮어쓰기) |
>> | 표준 출력을 파일에 씀 (이어쓰기) |
<< | heredoc: 지정한 구분자가 나올 때까지 입력을 읽어 표준 입력으로 전달 |
환경 변수 확장
명령어 내의 $VAR 형태를 해당 환경 변수의 값으로 치환한다. $?는 직전에 실행한 명령어의 종료 상태(exit status)로 치환된다.
내장 명령어 (Builtin)
execve로 실행할 수 없는 셸 내부 명령어들을 별도로 구현했다.
| 명령어 | 기능 |
|---|---|
cd | 현재 디렉토리 변경 |
echo | 텍스트 출력 |
pwd | 현재 디렉토리 경로 출력 |
export | 환경 변수 설정 |
unset | 환경 변수 삭제 |
env | 환경 변수 목록 출력 |
exit | 셸 종료 |
시그널 처리
ctrl-C, ctrl-D, ctrl-\ 입력이 bash와 동일하게 동작하도록 SIGINT, SIGQUIT 시그널을 처리한다.
히스토리
위/아래 화살표 키로 이전에 입력했던 명령어를 조회하고 재사용할 수 있다.