특정 실행파일을 직접 만들어서 minishell 안에서 실행시켜야 한다. 만들어야 하는 함수는 총 7개이다. ( cd
, pwd
, echo
, env
, export
, unset
, exit
)
char *getcwd (char *buff, size_t buff_size)
getcwd
는buff
에 현재 절대경로를 할당한다.- 반환값
- 성공 시 buff에 NULL이 아닌 값
- 실패 시 NULL
현재 절대경로를 출력하는 함수이다. 따라서 getcwd만 사용하면 바로 구현할 수 있다.
int chdir(const char *path)
- 현재 작업 디렉터리를 변경한다.
- path : 변경할 디렉터리 경로
- 반환값
- 성공 시 0
- 실패 시 -1
상대경로, 절대경로를 고려해서 위치를 이동시키는 함수이다. 마찬가지로 getcwd()
를 사용해서 현재 경로를 구한 뒤 chdir()
을 사용해서 입력받은 경로로 이동해야 한다.
특징 1
$cd . #현재 폴더
$cd .. #현재 폴더의 상위 폴더
$cd ~ #루트 경로
.
, ..
은 경로 중간에 들어가도 괜찮은 듯 하지만 ~
은 경로 중간에 들어가면 오류를 뱉는다. 항상 가장 처음에 와야 한다.
특징 2
$cd /minishell #오류 반환
$cd ./minishell #정상 이동
가장 처음에 /
가 와도 오류를 뱉는다. 이런 부분은 어떻게 고려해야 하는지 고민했는데 chdir을 사용하면 쉽게 해결...!
고려사항
cd ~
는 직접 구현해야 함$PWD
의 값은 변하지 않는다. 따라서 환경변수의 값을 수동으로 관리해야 한다.$PWD
의 값이 변경된 경우, 이전 $PWD
를 의미하는 $OLDPWD
의 값이 추가된다.unset PWD
로 PWD의 환경변수를 삭제한 경우, cd로 PWD의 값이 변경돼도 환경변수가 새로 생기지 않는다. 이 함수는 모든 환경변수를 출력하는 함수이다.
cd함수를 만들면서, 환경변수를 고려해야 하는 함수가 많다는걸 깨달았다...! cd
, echo
, export
, unset
모두 환경변수를 고려해야 한다. 그래서 우선 env
를 만들기로 했다.
우리 팀은 환경변수를 연결리스트로 새로 만들어서 관리하기로 했다. 수정 / 삭제가 필요하기 때문에 원활한 관리를 위해 다음과 같이 구조체를 설정했다.
typedef struct s_env
{
char *key;
char *value;
struct s_env *next;
} t_env;
연결리스트만 잘 만들어주면 그 연결리스트를 형식대로 출력하면 되므로 간단히 완성했다.
export는 인자가 없을 때 환경변수의 값을 출력하고, 인자가 있을 때 환경변수를 추가/수정하는 함수이다.
인자가 없는 경우 간단히 출력만 하면 되고, 인자가 있는 경우 신경써야 할 조건이 많다. 여러개의 부속 함수를 만들어서 아래의 고려사항을 충족하는 함수를 만들었다.
개인적으로 빌트인 함수 중 가장 고려할 부분이 많아서 구현이 까다로웠다.
고려사항
환경변수명=값
의 형태로 받아와야 한다. 띄어쓰기 금지! =
이 없는 경우에도 값을 추가한다. 다만 env로 출력되지는 않는다.=
이 여러개일 때 가장 처음 나온 문자를 기준으로 split한다. 내 로직
export가 환경변수를 추가하는 함수였다면, unset은 환경변수를 삭제하는 함수이다.
고려사항
echo는 인자로 받은 값을 터미널에 출력하는 함수이다. 빌트인 함수 중 유일하게 옵션을 신경써야 하는 함수이다.
고려사항
-n
옵션, 해당 옵션을 사용할 시 개행을 모두 제거하고 출력해야 한다. -nnnnnnnnnnnn
도 n옵션으로 처리해야 한다. (-n2n
은 해당 안 됨)-n -n -n -n -n
도 n옵션으로 처리해야 한다.$
로 시작하는 인자는 환경변수의 value을 출력해야 한다. (이건 파싱할 때 처리해야 함)exit은 프로세스를 끝내는 함수이다. 인자가 있는 경우, 없는 경우 모두 고려해야 한다.
고려사항
exit: too many arguments
라는 오류 문구와 함께 터미널로 돌아가야 한다. (프로세스가 종료되지 않음)numeric argument required
라는 오류 문구와 함께 프로세스가 종료돼야 한다.