# Lab: Shell

이 실습에서는 기본적인 Unix 셸을 구현할 것입니다. 이 셸은 명령어를 입력받아 해당 명령어를 실행하는 아주 간단한 구조로 되어 있습니다. 이 과정을 통해 리눅스 프로그래밍 환경에 익숙해지고, 프로세스 생성, 관리, 소멸에 대해 배우며, 셸이 필요로 하는 기본적인 기능들을 경험하게 됩니다.

## 프로그램 명세

### 기본 셸: `chesh`

당신의 기본 셸, `chesh`(Cheju Shell의 약자)는 사용자로부터 명령어를 입력받아 실행하고 결과를 출력하는 반복 구조를 가집니다. 사용자가 `exit`를 입력하기 전까지 이 과정은 계속됩니다.

- 인터랙티브 모드: 사용자가 직접 명령어를 입력할 수 있습니다.
- 배치 모드: 명령어가 담긴 파일을 읽어 해당 명령어들을 순차적으로 실행합니다.

### 명령어 실행

- 셸은 각 명령어를 별도의 프로세스로 실행해야 합니다(`fork()`, `exec()`, `wait()` 사용).
- 초기 셸 경로는 `/bin` 디렉토리를 포함해야 합니다.

### 내장 명령어

- `exit`: 셸을 종료합니다.
- `cd`: 현재 디렉토리를 변경합니다.
- `path`: 실행 파일을 검색할 경로를 설정합니다.

### 프로그램 오류 처리

- 오류 발생 시 "An error has occurred\n" 메시지를 출력하고, 적절하게 처리합니다.

## 구현 팁

1. **기본 기능 구현**: 한 번에 하나의 명령어 실행에서 시작합니다.
2. **내장 명령어 추가**: `exit`, `cd`, `path` 같은 내장 명령어를 구현합니다.
3. **입력 처리**: 공백, 탭 등 다양한 공백 문자를 적절히 처리할 수 있도록 합니다.
4. **오류 검사**: 모든 시스템 호출의 반환값을 검사하여 오류를 적절히 처리합니다.
5. **테스트**: 다양한 입력과 상황을 가정하여 셸이 올바르게 동작하는지 테스트합니다.

## 예제 코드

예제 코드는 [`src/ostep/processes-shell/chesh.c`](https://github.com/chu-aie/os-2024/blob/main/src/ostep/processes-shell/chesh.c)에 있습니다. 이 코드는 `chesh` 셸의 기본적인 동작을 보여주며, 추가적인 기능을 구현하여 확장할 수 있습니다.

## 실행 방법

리눅스 환경에서 위의 기본적인 셸 프로그램 `chesh`를 컴파일하고 실행하는 방법을 단계별로 설명하겠습니다. 이 튜토리얼은 GCC(GNU Compiler Collection)가 설치된 리눅스 시스템을 기준으로 합니다.

### 1단계: 코드 저장하기

위에서 제공된 C 코드를 `chesh.c`라는 이름의 파일로 저장합니다. 이 작업은 텍스트 에디터를 사용하여 수행할 수 있습니다. 예를 들어, `nano`, `vim`, `gedit` 등의 에디터를 사용할 수 있습니다.

```bash
nano chesh.c
```

위 명령어는 `nano` 텍스트 에디터를 사용하여 새 파일을 생성하거나 기존 파일을 편집할 때 사용합니다. 위 코드를 복사하여 에디터에 붙여넣고 저장 후 종료합니다(`Ctrl + X`, `Y`를 누르고 `Enter`를 눌러 저장).

### 2단계: 코드 컴파일하기

`gcc`를 사용하여 `chesh.c` 소스 파일을 컴파일하고 실행 파일을 생성합니다. 다음 명령어를 사용합니다:

```bash
gcc chesh.c -o chesh
```

이 명령어는 `chesh.c` 파일을 컴파일하여 `chesh`라는 실행 파일을 생성합니다. `-o chesh` 옵션은 출력 파일의 이름을 지정합니다.

```{note}
만약 `gcc` 컴파일러가 설치되어 있지 않다면, 대부분의 리눅스 배포판에서 `sudo apt install build-essential` (Debian, Ubuntu 등) 또는 해당 배포판의 패키지 관리자를 사용하여 설치할 수 있습니다.
```

### 3단계: 셸 실행하기

컴파일이 성공적으로 완료되면, 생성된 `chesh` 실행 파일을 다음과 같이 실행할 수 있습니다:

```bash
./chesh
```

이 명령어는 현재 디렉토리에 있는 `chesh` 실행 파일을 실행합니다. 성공적으로 실행되면, 사용자에게 명령어 입력을 위한 프롬프트 `chesh> `가 표시됩니다.

### 4단계: 명령어 실행하기

`chesh` 셸이 실행되고 나면, 다양한 리눅스 명령어를 입력하여 실행할 수 있습니다. 예를 들어, 현재 디렉토리의 파일 목록을 보려면 `ls` 명령어를 사용합니다:

```bash
chesh> ls
```

또는 현재 디렉토리를 변경하려면 `cd` 명령어와 함께 원하는 경로를 입력합니다:

```bash
chesh> cd /path/to/directory
```

### 5단계: `chesh` 종료하기

`chesh` 셸을 종료하려면, 내장 명령어인 `exit`을 입력합니다:

```bash
chesh> exit
```

이 튜토리얼을 따라 하면, 기본적인 셸 프로그램 `chesh`를 컴파일하고 실행하여 간단한 명령어를 수행할 수 있습니다. 추가 기능이나 개선이 필요한 경우, 소스 코드를 수정하여 더 많은 기능을 구현할 수 있습니다.
