Minishell

구름코딩·2021년 1월 16일
0

minishell 만들기 - 42

목록 보기
1/1

42 과제

쉘 만들기

요구사항

  • 새 명령을 기다릴 때 프롬프트 표시
  • bash와 같은 올바른 실행 파일 검색 및 시작
    • (PATH 변수 기준 또는 상대 경로 또는 절대 경로를 통해)
  • bash와 같은 기본 기능을 구현해야 한다
    • echo : '-n' 옵션
    • cd : 상대경로 또는 절대경로만
    • pwd : 옵션 없이
    • exprot : 옵션 없이
    • unset : 옵션 없이
    • env : 옵션과 매개변수도 없이
    • exit : 옵션 없이
  • ; : commands에서 명령을 분리해야 한다 (bash와 같다)
  • '" : 다중 행 명령을 제외하고 bash에서처럼 작동
  • 리디렉션 <, >, >> : file descriptor aggregation을 제외하고 bash에서처럼 작동
  • | (파이프) : bash에서와 같이 작동
  • 환경변수 ($문자) : bash에서와 같이 작동
  • ctrl + c, d, \ : bash에서와 같이 작동

기본 bash에서의 작동

echo

  • 옵션 없이 : 에코 후 개행
  • 옵션 -n : 에코 후 개행하지 않음

cd

  • 주어진 상대 또는 절대 경로로 current working directory를 이동

pwd

  • current working directory를 출력

export

  • 옵션 없이 : 환경변수 목록 출력
  • 매개변수와 같이 : 환경변수를 전연변수로 등록
    • export NAME=value : 환경변수 등록
    • export : 모든 환경 변수 출력

unset

  • 옵션없이 인자만 : 환경변수 설정한 값을 지워준다
    • unset NAME

env

  • 옵션없이 : 전역 환경 변수 목록을 출력

exit

  • 옵션없이 : 종료

;

;

  • 명령어 분리

', "

', " (따옴표)

  • 토큰 구별용
    • export LOGNAME=woonsik
    • echo “”$LOGNAME”hello” -> woonsikhello
    • echo ""$LOGNAME cc"Hi~" -> woosik ccHi~

<, >, >>

<, >, >>

  • 리다이렉션 (redirection)

    • < : 입력 리다이렉션

    • > : 출력 리다이렉션

      • 출력된 파일은 존재하지 않을 경우 자동생성
      • 만약 이미 존재하는 경우 덮어쓰기
    • >> : >와 같지만 이미 파일이 존재하는 경우 append(데이터를 추가)한다

      • < words.text sort > words2.text
      • words에 들어있는 단어가 sort의 입력으로 사용되어 전달되며 그 결과를 words2.text로 출력한다


입력으로 words.text를 주고 sort후 words2.text로 출력한 모습


입력으로 words.text를 주고 sort후 기존의 words2.text에 append(추가)한 모습

|

| (파이프)

두 명령문 사이의 수식막대를 지칭한다. 파이프는 쉘에게 왼쪽 명령문의 출력결과가 오른쪽 명령문의 입력값으로 사용된다라고 전달하는 역활을 한다


wc : “word count”의 축약어로 파일의 라인 수, 단어수, 문자수를 출력한다
왼쪽 wc 명령문의 결과를 |를 통해 오른쪽 head 명령문에 전달 해주고 거기서 -n개의 라인을 출력하는 모습

문자열 파싱 과정

미니쉘 프로그램을 실행해서 명령을 받아서 처리하는 일련의 과정

개요

  • scanner -> parser -> executer -> command
  • token 리스트 -> 추상구문트리 -> 실행 단위로 만들고 -> 실행-실행

과정

    1. get_next_line 으로 프롬프트에서 전체 문자열을 받는다.
    1. 문자열 첫번째 index=0 부터 공백분자(' ')가 나올 때 까지 검색을 한다.
    1. 공백문자를 기준으로 토큰을 나눈다.
    • 3-1. 토큰의 경우가 여러가지이기 때문에 잘 살펴 보아야 합니다.

    • 3-2. abcd efgh -> 두개의 토큰 abcd, efgh 가 생깁니다.

    • 3-3. abcd efgh -> 상기 동일 (abcd, efgh)

    • 3-4. 공백을 주의 해야 합니다!!! 공백은 아래 경우를 제외 하고 토큰문자에 포함될 수 없습니다.

    • 3-4. , 안에 들어 있을 때

      • 3-4-1. 쌍따옴표(dquote 라고 부르겠습니다.)
      • 3-4-2. “hello world” -> 하나의 토큰 hello world 가 생깁니다.
      • 3-4-2. “”hello world“” ->두개의 토큰 hello, world 가 생깁니다. 왜냐하면 “”<- 하나가 토큰이 생성되고, “” 안에는 아무런 문자도 없기 때문에 빈 문자열이 생성되는데,빈 문자열은 토큰이 만들어 질 수 없습니다.
      • 3-4-3. “” "hello world” “” 마찬가지로 하나의 토큰이 생성 됩니다.
      • 3-4-4. “‘hello world’” <- 하나의 토큰 ‘hello world’ 가 생성됩니다. dquote로 둘러 쌓여 있는 홑따옴표(squote라고 부르겠습니다.)를 주의 해야합니다.
        dquote 안에 있는 squote는 토큰에 포함되는 문자 입니다.
    • 3-5. squote도 3-4-4를 포함하여 dquote를 포함한 규칙과 동일하게 작동합니다.

      • 3-5-1. 그러나 몇가지 다른 부분이 있습니다. 환경 변수와도 관련이 되어 있어 아래에 설명 하겠습니다.
    1. 토큰을 나눈 후 $로 시작하는 문자열을 환경변수 목록과 비교하여 교체
    • 4-1. squote에 들어간 문자열의 경우 $가 들어 있어도 환경변수 교체작업을 하지 않습니다.
    1. 환경변수는 main에서 envp 파라미터(인자)를 받아와서 사용합니다.
    • 5-1. 환경변수는 key, value 의 구조체 t_env에 저장하여 linked list에 담아 놓았습니다.

추상구문트리

Abstract Syntax Tree - AST

  1. 어휘 분석기 (스캐너)는 코드 문자열을 토큰 목록으로 변환
  2. 구문 분석기 (파서, parser)는 어휘 분석 후 만들어진 플랫한 토큰 목록을 가져와서 언어 구문을 검증하고 (구문 오류가 있다면 에러를 표시) 트리 구조로 변환한다

AST를 만들때 각 노드 별 개요도

// command line

/*
1. job ; command line
2. job ;
3. job
*/

// job

/*
1. command | job
2. command
*/

// command

/*
1. simple_command redirection_list
2. simple_command
*/

// redirection_list

/*
1. redirection redirection_list
2. empty
*/

// redirection

/*
1. > filename
2. < filename
3. >> filename
*/

// simple_command

/*
1. pathname token_list
*/

// token_list

/*
1. token token_list
2. empty
*/

command노드를 simple command와 redirection으로 나누는 부분

cat > a > b < c이 입력으로 들어온 경우

의미 : 입력값을 a에 넣겠다 -> b에 넣겠다 <- c의 내용을 넣겠다
결과 : a는 지워지고, c의 내용이 b에 들어간다. 여기서 a, b, c는 파일이름이며 모두 이미 존재해야한다
구현 : 파일 a를 parents로 잡고 리다이렉션 정보를 a노드에 넣어주고 좌측 노드에 simple cmd를, 오른쪽 노드에 <redirection list>를 넣어주자

           command
         /        \
  simple cmd      redirection
  /                      \ 
cat                        >
                          /  \
                       aaaa   >
                             /  \
                          bbbb   <
                                 /
                               cccc 

AST로 나타낸 모습

          (일단 보류) 
        /        \
   cat            >
                 /  \
              aaaa   >
                    /  \
                 bbbb   <
                       /
                    cccc 

AST로 나타낸 모습 2

         (일단 보류) 
        /        \
   cat            aaaa (type : NODE_REDIRECT_IN)
                    \
                    bbbb (type: NODE_REDIRECT_IN)
                      \
                      cccc (type: NODE_REDIRECT_OUT)

AST로 나타낸 모습 3

         aaaa (type : NODE_REDIRECT_IN)
      /      \
    cat       bbbb (type: NODE_REDIRECT_IN)
                 \
                 cccc (type: NODE_REDIRECT_OUT)

로직

command를 두개의 구조로 중 하나로 확인한다

  • 1 - simple-cmdredierection-list구조
  • 2 - simple-cmd구조

1. simple command인 경우

먼저 simple-cmd인지 확인하게되면

    1. pathnametoken-list구조인지 확인하고

pathname을 처리한 후, token-list구조에 대해서 둘중 하나인지 체크한다

    1. tokentoken-list 구조
    1. EMPTY

1번의 tokentoken-list 구조라면 다시 재귀적으로 toekn, toekn-list를 확인하는 과정을 거치게 되고 그렇게 모든 토큰을 확인하면서 연결리스트를 만들게된다

2. redirection list인 경우

redirection-list를 확인하게 되는 경우에는

    1. redirectionredirection-list구조
    1. EMPTY

중 하나의 경우를 확인하게 되고 (1)번의 경우 redirection에 대해서

    1. > filename
    1. < filename
    1. >> filename

3가지의 경우를 체크해서 꺽쇠 정보와 filename정보를 받아서 노드를 생성하여 리스트에 추가해준다

이후에 redirection-list부분을 재귀적으로 다시 확인하면서 반복하게 된다

profile
내꿈은 숲속의잠자는공주

0개의 댓글