📚 /42seoul 시리즈

1. 소개


As beautiful as a shell

42서울 본과정 입과 후 여덟번째로 수행한 과제로, 작은 크기의 shell을 구현하는 과제이다. 우리는 이제 간단한 빌트인 함수부터 여러 명령어를 수행할 수 있는 간단한 shell을 만들어야 한다. 동굴 벽에 흐릿하게 비치는 bash를 구현하는 것이 목표인 것이다. 너무 큰 shell을 만들기 위해서 노력하다가 블랙홀에 빠지지 않게 조심하자.

shell의 내부 구현 (forkexecv를 활용한 명령어 처리 등) 은 이미 이전 과제인 pipex 과제에서 진행한 바 있다. 따라서 pipex의 핵심 로직을 바탕으로 각종 명령어와 파싱부분을 구현해 조합하는 프로젝트가 되겠다. 컴파일러 개론을 들었거나, 시간적 여유가 많았다면 파싱부분도 깔끔하게 트리로 할 수 있었겠지만 현실적인 문제로 도전하지 못한 것이 아쉽다. 다행히 파싱부분은 뛰어난 팀원분께서 인고의 예외처리를 통해 구현해주셨다!



2. minishell 명세서




3. 개념 정리


3-1. Shell

Shell은 사용자가 OS와 상호작용할 수 있도록 해주는 프로그램이다. 사용자가 명령어를 입력하면 이를 OS가 이해할 수 있도록 해석하고, 그에 따른 작업을 수행한다. Shell은 커맨드 라인 인터페이스를 제공하며, 사용자의 명령어를 읽고-해석하고-실행하고-결과를 출력한다.

shell에는 Bash, Zsh 등등 다양한 종류가 존재한다. 이때 Bash는 가장 널리 사용되는 shell이고, 클러스터 맥에 설치되어있는 기본 shell 이기도 하다. bash의 동작을 잘 뜯어보면서 과제를 수행해보자.


3-2. 환경 변수

환경 변수는 운영 체제에서 프로그램이 실행되는 동안 사용할 수 있는 변수이다. 이 변수들은 시스템 전체에 걸쳐 정보를 전달하거나 설정을 저장하는 데 사용된다. 환경 변수는 주로 시스템 경로, 사용자 정보, 설정 정보 등을 담고 있다.


3-3. built-in 함수

과제 상 구현해야하는 built-in 함수의 정체는 무엇일까?

Shell에서 built-in 함수란 Shell 자체에 내장된 명령어 또는 기능을 의미한다. 이러한 함수는 별도의 외부 프로그램을 실행하지 않고, Shell 자체에서 직접 수행된다. 이는 특정 작업을 보다 빠르게 수행할 수 있게 하며, Shell 스크립트에서 자주 사용되는 기본적인 작업들을 처리하는 데 유용하다.

이 말은 즉슨, 해당 함수들은 환경변수 PATH가 변경되거나 망가지는 일이 있어도 정상적으로 동작해야한다는 점! 또한 Shell 자체에서 실행한다는 점을 곱씹으면, built-in 함수를 실행할 때는 fork를 사용할 필요 없다는 것도 알 수 있다.



4. Mandatory


이번 과제는 2인이 협동해야하는 팀 과제이다. 주로 역할분배는 명령어 파싱부실행부로 구분하곤 한다.

명령어 파싱의 경우 bonus를 고려하지 않으면 주로 연결리스트로 관리를 하고, bonus를 고려할 경우 트리형태로 관리한다. 실행부의 경우 아까 언급한 것 처럼 이전 과제인 pipex와 유사하기 때문에 익숙한 작업이 주를 이룬다.

내가 실행부 + built-in 함수를 맡았고, 함께한 팀원분이 파싱부 + here_doc 등을 맡았다.

이에 따라, 이번 과제 정리는 내가 담당한 빌트인 함수만 주로 다루어보고자 한다. (실행부는 pipex와 유사). 코드를 실제로 나열하기보다는 각 함수들이 어떠한 특징을 가지고 있는지 알아보자! 함수들의 작동은 모두 bash을 기준으로 작동을 확인해보자. 직접 디렉토리 삭제 및 복구, 이상한 값들, 기괴한 상황을 bash에서 진행해보며 맞춰보는 것이 좋다. 생각보다 man page에 모든 것이 나와있지는 않음…


4-1. built-in 구현

ft_cd


ft_echo


ft_env


ft_exit


ft_export


ft_pwd


ft_unset



5. Evaluation


2025.05 코드 리뷰 추가 삽입

try1 - review 1

try1 - reivew 2

try1 - review 3

과제 크기가 크다 보니 평가 한번 받는데 기본 1시간 이상 걸렸던 것 같다. 해당 과제에서도 수많은 leak과 세그먼트 오류들을 마주했다. 특히 파싱 담당하신 팀원분이 상당히 고생이 많으셨다.

평가 중 특정 상황에서 abort 가 발생하는 문제가 발생했다. 아마 그 시점부터 1시간 동안 gdb를 켜서 평가자분과 함께 한줄 한줄 따라갔던 것으로 기억한다. 다만 평가지에 readline 내부의 문제점이 있을 수도 있다고 적혀있었고, 유일하게 의심스러운 부분이 readline 쪽에서 발생했기 때문에 평가를 마쳤다.

팀 과제이기도 했고, 함수와 파일이 정말 많아지기도 해서 이름들이 좀 헷갈리는 경우가 많았다. 그래서 중간 지점에 제미나이로 함수 이름을 추천 받아 반영했다. 가독성이 나쁘지 않았다.



6. Reference