C로 만든 첫 번째 쉘 프로젝트: 성공한 것과 실패한 것에 대한 진실
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
개발 툴
대상자
- C 프로그래밍 및 시스템 콜, 쉘 구현에 관심 있는 개발자
- 중급 이상의 기술 수준 (시스템 프로그래밍, 프로세스 관리, 신호 처리 지식 필요)
핵심 요약
- 성공한 기능:
- 외부 명령어(ls
, grep
) 및 내장 명령어(cd
, pwd
) 실행
- 파이프라인(ls | grep foo
) 및 배경/전경 작업(fg
, bg
, jobs
) 지원
- 변수 확장($VARIABLE
, $?
) 및 리디렉션(>
, <
, >>
) 처리
- 실패한 요소:
- 파이프라인 구현 시 setpgid
호출과 사용하지 않는 파이프 엔드 닫기 누락으로 인한 데드락 발생
- tcsetpgrp
사용 시 부모 프로세스에서만 호출해야 함을 오해
- 핵심 학습:
- fork
후 모든 자식 프로세스에서 setpgid
즉시 호출해야 프로세스 그룹 관리 가능
- 파이프 엔드는 부모/자식 모두에서 닫아야 데이터 흐름 차단 방지
섹션별 세부 요약
1. 소개
- C 프로그래밍 학습 후 첫 번째 프로젝트로, 시스템 콜(
fork
,exec
,signal
) 이해를 위해 쉘 개발 - 목표: 쉘 구조, 실패 요인, 학습 내용 정리
2. 프로젝트 개요
- 구현 기능:
- 외부 명령어 실행, 내장 명령어(cd
, exit
, jobs
) 처리
- 파이프라인, 배경 작업, 변수 확장 지원
- 사용 기술:
- gdb
, valgrind
디버깅, Makefile
빌드 자동화
3. 성공한 기능
- 토크나이저:
- 쿼터('
, "
), 이스케이프 문자 처리
- 리디렉션:
- >
, <
, >>
지원
- 파이프라인:
- ls | grep foo
실행 가능
4. 실패한 요소
- 파이프라인 구현 오류:
- setpgid
호출 누락으로 프로세스 그룹 관리 실패
- 사용하지 않는 파이프 엔드 닫기 누락으로 데드락 발생
- 신호 처리 오류:
- SIGCHLD
블로킹 미흡으로 자식 프로세스 처리 실패
5. 향후 개선 계획
- 기능 추가:
- 명령어 이력(↑/↓
키), 탭 완성, 헤드록(cat <
- 테스트:
- 단위/통합 테스트 개발, 최적화된 자료구조 연구(링크드 리스트 + 해시 테이블 대체)
결론
- 핵심 팁:
- 파이프라인 구현 시 모든 프로세스에서 사용하지 않는 파이프 엔드 닫기
- setpgid
는 부모/자식 모두에서 즉시 호출해야 프로세스 그룹 관리 가능
- tcsetpgrp
은 부모 프로세스에서만 호출해야 데드락 방지
- 실무 적용:
- 시스템 프로그래밍 학습에 유용한 예제, fork
, exec
, pipe
사용법 정리