Shell을 소개합니다.


Shell 이란 하나의 program이다. 그러나 다른 program과 다르게 사용자와 대화를 주고 받으며 동작하는 프로그램인 것이다. 전통적으로 여러가지 shell이 존재해왔었다. 그러나 최근에 가장많이 사용하는것은 bash(Borune shell)과 dash(Debian shell)이다. Shell마다 세부적인 기능은 다르지만 C-shell이나 오래된 몇가지 shell을 제외하고는 대부분 기능이 대동소이 하다.

 

 

History

초기의 computer system에서는  시스템에서만 해석이 가능한 기계어 파일을 직접 입력 받아 실행하였다그러나 human readable  명령어를 system에게 내리기 위한 program 필요하게 되어 이를shell이라는 이름으로 만들게 되었다. shell이란 이름은 다른 program 실행할  있으며, low level 가려져 있다는 뜻에서 지어졌다.

 

초기에 만들어진 shell Thomson shell, Mashey shell 이라고 하며 당시는 단지 batch job 하는 정도 였다고 한다현재 개념의 shell로는 Bourne shell 시초라고   있으며이는 개발자(http://www.computerworld.com.au/article/279011/a-z_programming_languages_bourne_shell_sh/?이름을 따서 만들어 졌다.

이후 bill joy 의해 C 문법이 가능한 c-shell 만들어졌으며, Bourne shell 발전시킨 Ksh(Korn shell) 등장하였고, csh 발전시킨 tcsh 등장하게 되었다. FSF 재단이 설립되면서 free shell 필요해져, Bourne shell계열을 발전 시킨 bash(Brian Fox 1988) 등장하게 되었으며이후 zsh까지 발전하게 된다.

 

Architect

이제 Shell 구조를 한번 살펴보자

보통의 일반 user process libc등의 library 매개체로 kernel system call 호출하는 구조로 이루어져 있다.

shell 이러한 일반 program 동일한 구조이나조금 특별한 성격을 가진다. user 하여금 직접 system call이나 system 접근할  있는 method 직접 호출   있도록 해준다예를 들어 사용자가chmod(system call중의 하나임) 입력하면 내부적으로 shell에서 입력을 받아 external program /bin/chmod 호출해주게 된다, system call 호출하는 wrapper 역할을 하게 된다.

 

 

 

Shell Start

Shell 시작하기 까지 대략적인 flow 살펴본다.

linux kernel start > init > /bin/login > shell

 

linux kernel start : boot loader이후 system 운영을 위해 다양한 kernel process 실행시킨다.

init : 다양한 시스템 초기화를 진행하고, getty process 띄워 STD in/out/error등을 제어하고 마지막으로 login prompt 띄운다.

/bin/login: 입력을 받으면 etc/passwd 파일을 열어 login ID/PASSWD 비교하고인가되면 passwd 파일에 기록된 HOME, SHELL, USER, LOGNAME 변수들을 설정해준다이때 SHELL 변수에는 passwd파일의 마지막 field 기록되어 있으며이를 참고하여 사용자에게 설정된 shell 띄워준다.

shell: 시작한 shell 기본적인 초기화를 진행하는데, login shell interactive shell 나눠 초기화 script 실행하게 된다.

  • login shell :  system 전체에 적용되는 초기화로 login할때 한번 실행
    /etc/profile > .bash_profile (존재하지 않을때만 > .profile  읽음)
  • interactive shell(nonlogin shell) : login shell이후 개개인에게 적용되는 초기화로 shell 시작할  마다 실행
    .bashrc(시작할때), .bash_logout(shell 종료시), .inputrc(line 읽을 때마다)

 

 

Command sequence (priority)

그러나 shell 한행씩 읽어 입력된 명령어를 다음과 같은 순서로 해당명령을 찾아 실행하게 된다.

alias > keyword > function > builtin > external program

구분 (type)

한글명

설명

확인법

bash에서만

alias

별명

shell init script에서 선언한 user defined command

>alias

compgen -a

keyword

키워드

조건 제어문으로 if, else, for, while, 등의 구문으로 문장의 끝을 판별한다.

>complete -A keyword :

> : <tab> <tab>

compgen -k

function

함수

alias 비슷하지만 function 형태로 등록된 user defined command

>set or >typeset, >declare

compgen -A function

builtin

내장명령

shell default 탑재되어 있는 default command

>help or >enable

compgen -b

external program

외장명령

path 걸려있는 곳에서 실행되는 모든 program

>ls '해당 path'

compgen -c

bash 모든 명령(from alias to external programs) 출력 : compgen -A function -abck

ex)  compgen -A function -abck |grep ffvi,  compgen -c |grep ffvi

특정 명령이 어떤 command type 속하는지 알려면 type '명령어   있다.

 

여기서 alias > keyword> function > builtin 까지는 shell 내부에서 실행된다그러므로 RAM 상주하는 program으로  속도가 매우 빠르나 external program경우 /bin, /usr/bin, /usr/sbin 등의 file system 존재하는 외부에서  명령을 가져와야 함으로 느리게 된다.

예를 들어 앞에서 kill 명령을 수행할 경우이는 builtin 명령도 존재하고외장 명령(/bin/kill) 존재한다그러나 match 내장명령이 빠르기 때문에 builtin kill  수행된다마찬가지로 cd역시 그러하며이러한 명령들을 보려면 shell에서 help 명령을 치면 builtin 명령 list   있다. 

만약 external에만 존재하는 명령어가 입력되면 다음과 같은 과정을 거친다.

  1. 현재 shell fork 하여 자식 process 생성하고, wait 상태로 빠진다
    (참고 wait상태로 빠지지 않으면 자식이 zombie 되고부모가 먼저 종료될 경우 init 최종 부모 process 된다. )
  2. 생성된 자식은 exec 통해 external program 실행시킨다.
    (참고로 자식은 부모의 context 상속받는데이때현재 작업디렉토리환경변수현재 open파일리다이렉션등을 상속한다.)
  3. 자식이 종료(exit)되면, wait 하고 있던 부모가 깨어나면서 자식의 process 정보를 지운다.

마지막으로, shell에서 script 실행하게 되면현재 process에서 그냥 script 파일 line 하나하나를 실행하게 된다.

이때 중간에 external program 있으면 마찬가지로 fork & exec 하게 된다.