728x90
Minishell
As beautiful as a shell
요약: 이번 프로젝트의 목표는 간단한 셸을 만드는 것입니다. 맞아요. 당신만의 작은 bash나 zsh이요. 프로세스나 파일 디스크립터에 대해 아주 많이 배우게 될 겁니다.
간단한 쉘 만들기 프로젝트인 minishell을 위해 쉘에 대해서 알아보자.
Shell(셸/쉘)이란?
셸은 운영체제 상에서 다양한 운영 체제 기능과 서비스를 구현하는 인터페이스를 제공하는 프로그램이다. 셸은 사용자와 운영 체제의 내부(커널) 사이의 인터페이스를 감싸는 층이기에 껍데기라는 의미의 셸의 이름이 붙었다.
셀은 일반적으로 명령 줄과 그래픽 형의 두 종류로 분류된다. 명령 줄 셸은 운영 체제 상에서 CLI(Command Line Interface)를 제공하는 반면에, 그래픽 셸은 GUI(Graphic User Interface)를 제공한다.
셸에서 사용자는 프로그램을 실행할 수 있으며, 입력과 출력을 파일에서 가져오도록 리다이렉션할 수도 있다. 또한 셸은 함수, 변수 등과 같은 프로그래밍 구조를 제공한다. 셸 스크립트라고 불리는 셸 프로그램은 편집, 기록, 파일 완성, 와일드카드, 환경 변수 확장 및 프로그래밍 구성과 같은 기능을 제공한다.
셸의 기본 라이프타임
- Initialize : 초기화 단계에서 일반적인 셸은 구성 파일을 읽고 실행한다. 이것이 셸의 행동 양상을 바꾼다.
- Interpret : 해석 단계에서 셸은 stdin(파일이나 대화식일 수도 있음)으로부터 명령을 읽고 실행한다.
- Terminate : 종료 단계에서 명령이 실행 된 후 셸은 모든 종료 명령을 실행하고 메모리를 확보 한 후 종료한다.
셸의 기본 루프
- Read : stdin(표준 입력)에서 명령을 읽는다.
- Parse : 명령으로 받은 문자열을 프로그램과 arguments(인수)로 나눈다.
- Execute : 분석(파싱)된 명령을 실행한다.
Shell의 구성요소
- Lexer : 소스코드를 토큰 단위로 분석
- token : 쉘에서 입력을 처리하기 위해서 적절한 단위로 명령문을 나눠야 한다. 토큰은 명령문을 나누는 최소단위이다.
- Parser : ls -al과 같은 명령을 읽은 뒤 Command Table이라는 데이터 구조에 삽입해 실행될 명령을 저장한다.
- Executor : 명령 테이블의 모든 명령에 대해 새 프로세스를 생성한다. 필요한 경우 파이프( | )를 생성하여 한 프로세스의 출력을 다음 프로세스의 출력을 다음 프로세스의 입력으로 전달한다. 또한 표준 입력, 표준 출력 및 표준 오류를 리다이렉션( >, <, >> )한다.
- Shell Subsystems
- Environment Variables(환경 변수) : ${VAR}로 환경변수를 불러올 수 있다. 셸은 환경변수를 설정, 확인 및 출력할 수 있어야 한다.
- Wildcards : * 은 문자열 와일드 카드이다. 해당 디렉토리에서 내용이 일치하는 모든 파일을 불러온다.
- Subshells : ( ), $( ), | 를 이용해 한 명령의 출력값을 새 명령의 입력값으로 활용할 수 있다.
Shell에서 프로세스를 생성하는 방법
프로세스의 시작 방식과 진행 상황을 정확하게 알고있어야한다. Unix에서 프로세스를 시작하는 방법은 두 가지이다.
- Init
- fork() : 대부분의 프로그램은 Init이 아니기 때문에 프로세스를 시작하는 실질적인 방법은 fork() syscall 뿐이다. 이 기능이 호출되면 운영체제가 부모 프로세스로부터 자식 프로세스를 복제하여 두 프로세스를 병렬로 실행한다.
https://ko.wikipedia.org/wiki/%EC%85%B8
https://velog.io/@hidaehyunlee/minishell-1.-%EA%B3%BC%EC%A0%9C%EC%86%8C%EA%B0%9C-%EB%B0%8F-%EC%84%A0%ED%96%89%EC%A7%80%EC%8B%9D
https://brennan.io/2015/01/16/write-a-shell-in-c/
728x90
300x250