Published 2017. 1. 15. 01:41

유닉스나 리눅스를 공부하는 많은 초심자들이 처음으로 부닥치는 어려움이 바로 Shell(쉘) 이다. 이 쉘을 정확하게 이해하지 않으면 유닉스나 리눅스 서버에서 주로 업무를 하는 엔지니어가 되고자 하나 초심자 수준를 벗어날 수 없다. 그만큼 쉘을 정확하게 이해한다는 것은 유닉스나 리눅스의 운영체제를 얼마나 이해하고 있는지에 대한 수준을 가늠하는 하나의 지표로 써도 될만큼 중요하다.


  • 쉘의 정의


쉘(Shell)은 운영체제에서 사용자가 입력하는 명령을 읽고 해석하여 대신 실행해주는 프로그램이다. 여기서 쉘을 Unix나 리눅스에만 있는 것으로 생각한다면 오산이다. Windows 운영체제나 다른 운영체제에도 Shell은 필수적으로 존재한다.

운영체제는 로그인한 사용자가 없다면 하나의 쉘도 실행되지 않는 상태다. 

사용자가 로그인을 시도하면 운영체제는 ID와 패스워드를 받아들이는 로그인 프로그램을 실행하게 되고 사용자가 입력한 ID와 패스워드를 검증한 뒤 정상적인 사용자라면 쉘을 실행하여 사용자 세션을 쉘에게 넘겨준다.

쉘의 역할은 사용자가 입력한 명령을 해석하여 대신 실행해주는 것이다. 쉘의 내부 명령어라면 스스로 실행한 뒤 결과를 화면에 표시해주고 내부 명령어가 아니라면 PATH 환경변수에 지정된 경로에서 입력받은 명령과 같은 파일을 찾아 exec() 시스템콜을 호출하여 실행한 뒤 키보드와 마우스 등의 입력장치와 모니터에 해당하는 표준 출력장치의 제어권을 해당 프로그램에게 넘겨준 뒤 프로그램이 끝날 때 까지 대기하는 역할을 수행한다.


  • 쉘의 종류

Unix나 Linux의 경우 ps 명령을 실행하면 보이는 프로세스 중에서 bash, sh, ksh, csh 등이 쉘 프로그램이고 Windows의 경우 작업관리자에서 볼 수 있는 explorer.exe 가 쉘이라고 보면 된다. Windows의 경우 Explorer.exe 이외에도 cmd.exe가 추가적인 쉘로 지원되는데 이는 원래 DOS 시절의 잔재로서 DOS 호환을 위해 지원된다고 생각하면 된다.



위의 화면이 쉘이 실행중인 화면이다. 위의 화면에선 id 라는 명령어와 ps 라는 명령어 2개가 실행되었고 그 실행결과가 표시되었다. 그리고 각 명령이 실행된 뒤 다시 프롬프트 (#)이 표시되어 다음 명령을 기다리는 화면이다. 이렇게 입력과 실행을 반복하는 형태의 쉘을 대화형 쉘이라고 한다.

ps 명령이 실행된 결과를 보게되면 bash 라는 프로세스가 보이는데 bash가 바로 쉘이다. 프롬프트인 #이나 $를 화면에 보여주고 명령의 입력을 기다리는 역할을 수행한다. 서버에서 사용자 계정을 생성하게 되면 사용자가 로그인할 때 어떤 쉘을 실행시켜주어야 하는지를 지정하도록 되어 있다.bash는 리눅스에서 지원되는 기본 쉘로서 사용자 계정을 생성할 때 쉘을 특별히 지정하지 않으면 기본적으로 지정되는 기본 쉘이다.

여담으로 아주 오래전~?? 서비스되던 천리안이나 하이텔, 나우누리를 기억하는가? 파란 화면에 글자로만 가득찬 화면.. 그 화면이 바로 쉘을 대신하는 프로그램이 실행된 화면이다. 천리안이나 하이텔, 나우누리는 사용자가 텔넷 접속을 할 경우 ID와 패스워드를 검증한 뒤 bash와 ksh 같은 프로그램을 쉘로 지정하여 실행하는 대신 천리안이나 하이텔의 화면을 보여주는 직접 개발한 프로그램을 쉘로 지정하여 서비스를 했던 것이다. 이해가 되는가?




  • 쉘의 환경변수

쉘을 공부함에 있어 가장 중요한 것중 하나가 환경변수의 이해다. 쉘은 여러가지 환경변수를 사용하는데 이 환경변수는 사용자가 임의로 본인의 의지에 따라 값의 변경이 가능하다. 하지만 미리 정의된 환경변수의 이름을 변경해서는 안된다.(변경할 수도 없지만..) 환경변수는 쉘의 종류에 다라 설정하는 방법과 확인하는 방법이 다르다. 리눅스의 기본 쉘인 bash (본어게인쉘)에서는 아래와 같이 env 명령으로 확인할 수 있다. (csh의 경우 set 명령)



쉘은 사용자와 운영체제의 사이에 위치하는 프로그램이다. 사용자가 입력한 명령어를 신속하게 찾고 운영체제와 사용자 그리고 사용자가 실행한 다른 프로그램과의 소통을 위해 사용하는 것이 환경변수다. 

이 환경변수들은 사용자가 읽을 수만 있는 것과 변경이 가능한 것이 있다. 그 중에서 가장 대표적인 환경변수는 PATH가 있다.

 환경변수 PATH는 사용자가 명령을 입력하였을 경우 쉘은 내부 명령어 인지 확인하고 아닐 경우 해당 명령은 외부명령어 즉 실행파일인 것으로 간주한다. 만약 사용자가 /usr/bin/df 와 같이 Full Path를 입력하였다면  /usr/bin 디렉토리에 있는 df란 명령을 바로 실행할 수 있으나 사용자가 df 라고만 입력하였다면 쉘은 df라는 명령어가 어느 디렉토리에 있는지 알 수 없다. 이때 쉘이 df 라는 명령어를 어디에서 찾을 수 있는지를 정의해주는 환경변수가 바로 PATH 다. 위의 화면에서 보면 PATH 환경변수는 다음과 같다. ( echo 명령으로 특정 환경변수만 조회할 수 있다.)


[root@CentOS_100 ~]# echo $PATH

/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin


PATH 환경변수에는  : (콜론)을 구분자로 하여 여러개의 디렉토리가 나열되어 있는 것을 볼 수 있다. 쉘은 df 라는 명령이 입력되면 해당 명령어의 위치를 찾기 위해 가장 먼저 /usr/kerberos/sbin 디렉토리에 df 가 있는지 확인한다. 만약 없다면 다음에 있는 /usr/kerberos/bin 에서 찾고 거기에도 없다면 /usr/local/sbin 에서 찾게 된다. 이렇게 순서대로 PATH 변수 내의 디렉토리에서 명령을 찾다가 df 라는 명령어가 발견되면 그 파일을 실행시켜주는 것이다.

만약 PATH 환경변수에 지정된 경로에 해당 명령어가 없다면 명령어를 찾을 수 없다는 메시지를 뿌리며 에러를 리턴해준다.

모든 환경변수는 의미를 갖고 있으며 사용법과 환경변수를 참조하는 프로그램도 다양하다. 그리고 환경변수의 값이 잘못되어 있으면 오작동을 하는 경우도 많다. 특히 날짜와 시간을 사용하는 프로그램의 경우 환경변수 TZ (time zone), 펑션키를 사용하는 프로그램의 경우 TERM (Terminal) 환경변수, 한글을 사용하는 프로그램의 경우 LANG (Language) 환경변수 등은 잘못 설정될 경우 문제가 발생하는 경우가 많다.


  • 쉘 환경변수의 설정


쉘의 환경변수는 로그인 할 때 설정된다. 사용자 환경은 프로파일에서 설정되는데 프로파일은 글로벌 프로파일과 계정 프로파일 두가지가 있다. 그리고 이 프로파일의 파일위치와 이름은 운영체제와 쉘의 종류에 따라 조금씩 다르다.

sh, ksh 은 /etc/profile 과 사용자 홈디렉토리의 .profile 이다. 

리눅스의 bash는 /etc/profile과 /etc/bashrc 두개의 파일과 사용자 홈디렉토리의 .bashrc 가 환경변수가 설정될 수 있는 파일이다.

csh 은 /etc/csh.login (Unix 종류와 버전에 따라 다르나 대체로 login 이라는 이름이 붙음. 내용을 보면 확인 가능함)과 사용자 홈디렉토리의 .cshrc 이다.

이 프로파일의 내용을 보면 환경변수를 설정할 수 있는 방법을 짐작할 수 있다. 미리 정의된 환경변수 이외에도 사용자 환경변수를 추가하여 사용할 수 있다. 이 파일에 환경변수를 추가하고 다시 로그인한 뒤 env 명령을 실행하면 추가한 새로운 환경변수가 표시되는 것을 확인할 수 있다.

쉘에 대해 서술하자면 너무도 분량이 많아진다. 하지만 중요한 것은 쉘의 원리를 이해하는 것이 중요하다. 모든 지식이 그렇듯 단편적인 커맨드나 변수 이름만 딸랑 암기하는 것은 운영체제를 이해하는데 전혀 도움이 안되고 그런 지식은 죽은 지식이다. 쉘과 쉘의 환경변수가 어떤 역할을 하는지를 개념부터 이해하는 것이 중요하다. 쉘을 이해하였다면 쉘의 인터프리터 방식의 언어인 쉘스크립트에 대해 공부하는 것이 순서다.



출처: http://blogger.pe.kr/300 [taeho's life logger]

'리눅스 ( Linux ) > 리눅스' 카테고리의 다른 글

Raid 구성  (0) 2017.04.12
가상머신의 이해  (0) 2017.01.15
파일의 구성 및 종류  (0) 2017.01.15
커널이란?  (0) 2017.01.15
리눅스의 특징  (0) 2017.01.15
복사했습니다!