date
, echo
명령어를 실행해보고 존재하지 않는 명령어도 입력해본다.
리눅스 내부에서 명령어가 실행되는 과정을 살펴보자.
앞서 date
, echo
명령어를 실행할 때 내부에서는 다음과 같은 일이 일어난다.
- 키보드로 입력한 문자열을 받아들인다.
- 해당 명령어를 찾는다.
- 발견한 명령어를 실행한다.
- 실행한 결과로 얻은 문자열을 화면에 표시한다.
이 중에서 3번은 리눅스의 본체인 커널
이 수행한다.
커널
은 운영 체제의 중심에서 CPU나 메모리 같은 하드웨어를 관리하면서 명령어를 실행하고 프로세스를 관리한다.
리눅스에서는 사용자가 커널을 직접 조작할 수 없게 되어 있기 때문에 커널과 사용자 사이에서 명령어를 받아들이고 커널의 실행 결과를 출력하는 소프트웨어가 필요하다. 이 역할을 수행하는 소프트웨어가 바로 셸
이다. 즉, 셸
은 커널의 인터페이스에 해당한다.
정리하자면, 사용자가 셸에 date
문자열을 입력한다. 그러면 셸은 해당 명령어를 찾아서 리눅스 커널에게 실행을 의뢰하고, 리눅스 커널이 명령을 실행하면 셸은 그 결과를 전달받아 사용자의 화면에 출력한다.
사용자와 리눅스 커널 사이의 소통 창구 역할을 하는 것.
조개 껍질(shell)이라는 이름도 커널을 감싸 보호하기 때문에 붙여졌다고 볼 수 있다.
또한, 셸은 사용자의 의뢰를 받아서 커널에 전달하므로 메신저 혹은 비서라고 볼 수도 있다.
셸과 커널을 분리하게 되면 다음과 같은 이점이 생긴다.
'한 프로그램에 너무 많은 기능을 넣지 않는다'는 것이 리눅스의 기본 철학이다. 보통 한 프로그램에 기능을 많이 넣기보다는 적절히 분리하는 것이 좋은 설계 철학이다.
앞서 명령어를 입력할 때 다음과 같은 문자열을 볼 수 있는데, 이를 셸의 프롬프트(prompt)
라 한다. 프롬프트란 사용자에게 어떤 결정을 내리도록 한다는 의미이다. 즉, 셸이 사용자에게 명령어를 받아들일 준비가 되었음을 나타낸다고 보면 된다.
dongmin @ dongmin:~/Desktop$
(사용자이름) (호스트이름)
일반 사용자
는 $, 슈퍼 사용자(root)
는 #로 프롬프트를 표시하는 것이 일반적임을 알아두자.
리눅스에 로그인하면 셸이 사용자를 반기며 입력을 대기한다. 이는 사용자가 로그인할 때 리눅스가 자동으로 셸을 시작하기 때문이다. 이렇게 로그인 후 처음으로 시작되는 셸을 로그인 셸
이라 한다.
echo $SHELL
명령어를 통해 자신이 사용하고 있는 로그인 셸 확인이 가능하다.
/bin 디렉터리에 있는 bash가 바로 로그인 셸이다. 리눅스에서는 별도 지정하지 않으면 bash가 로그인 셸로 시작한다.
이처럼 명령어를 입력하고 그 결과를 보며 셸을 사용하는 조작 방식을 대화형(인터렉티브) 방식
이라 한다.
이에 반해 실행하고 싶은 명령어들을 미리 파일에 기록하고 그 파일을 셸에 넘겨주는 방식으로 도 명령 수행이 가능한데, 이렇게 일련의 명령어 흐름을 기술한 파일을 셸 스크립트
라 한다.
예시를 보자.
셸 스크립트
는 '작은 프로그램(명령어)을 조합해 복잡한 처리를 수행한다'는 리눅스의 철학이 담긴 강력한 도구이다.
로그인 셸이 배시(bash)인 것을 확인했다. 리눅스에서는 배시 외에도 다양한 셸이 있으며 작성된 시대나 개발자의 철학에 따라 특징이 다르지만, 마찬가지로 커널과 사용자의 인터페이스 역할을 수행한다. 대표적인 것만 살펴보겠다.
sh
- AT&T 벨 연구소의 스티븐 본(Steven Bourne)이 만들어서 본 셸(혹은 B셸)이라고도 불리며, 아주 오래전에 만들어진 셸이다. 리눅스뿐만 아니라 FreeBSD나 Solaris, HP-UX, AIX 등 여러 운영 체제에서 사용할 수 있다.
- sh는 긴 역사를 통해 표준 셸의 지위를 가지고 있으며, 현재도 셸 스크립트를 작성할 때는 sh를 사용하는 것이 일반적이다. 하지만 오래된 셸이라 기능이 적고 특히 대화형에서 사용하기에는 불편하다. 따라서 로그인 셸로 사용되는 경우는 거의 없다.
csh
- csh도 무척 오래된 셸 중 하나로 C셸이라 불린다. sh보다 대화형 조작에 편리한 기능을 갖추고 있어 인기가 많다. 하지만 셸 문법이 sh와 크게 달라 셸 스크립트 작성에는 적합하지 않다.
현재는 csh의 뒤를 잇는 tcsh가 나와 많이 사용하지 않는다.
bash
- sh를 바탕으로 기능이 추가된 셸이다. sh와 호환성이 있어 sh를 대체할 수 있다. 또한, 대화형 조작에 필요한 기능을 갖추고 있어 많은 리눅스에서 기본 로그인 셸로 사용하고 있다. 셸 스크립트를 작성하는 데도 적합하다.
tsch
- csh에 이어 개발된 C셸 계열의 셸이다. 대화형 조작에 편리한 기능을 많이 갖추고 있지만, csh와 마찬가지로 셸 스크립트에는 적합하지 않다. 참고로 tcsh 등 C셸 계열에서는 일반 사용자 프롬프트가 $이 아닌 %이다.
- tcsh는 현재 FreeBSD의 로그인 셸로 사용되고 있지만, 사용자는 점점 줄고 있다.
zsh
- 비교적 최근에 개발된 셸로, bash와 tcsh의 기능에 독자적인 기능이 추가되었다. 무척 다양한 기능을 갖추고 있어 메뉴얼만 17개 섹션에 달한다.
모든 기능을 익히는 데 시간이 걸리지만, 익숙해지만 작업 효율을 크게 높일 수 있다.
bash
셸을 추천한다.
sh
셸도 중요한 셸이다. 오랫동안 널리 사용되었기에 sh로 작성된 셸 스크립트도 많고 이 때문에 현재도 sh가 사용되고 있다. 리눅스가 시작되면 sh의 셸 스크립트가 실행되며, 명령인 줄 알았지만 실은 sh 셸 스크립트인 경우도 있다.
셸도 하나의 명령어에 불과하므로 사용하고 싶은 셸 이름을 입력하고 실행하면 바꿀 수 있다. 리눅스에 기본으로 포함된 sh
셸로 변경해보자.
다시 원래 셸 bash
로 돌아간 것처럼 보이지만, 실은 bash -> sh -> bash
를 기동한 상태이다. 즉, 셸 위에 셸이 중첩되어 실행된 것.
이렇게 셸 위에서 기동한 셸은 로그인 셸이 아닌 일반 셸(비로그인 셸)이다.
비로그인 셸에서는 logout 명령어로 종료할 수 없기에 아래와 같이 오류가 발생한다.
비로그인 셸에서 빠져나오려면 exit
명령어를 사용한다. 원래의 배시 셸로 돌아오기 위해서는 exit
를 두 번 입력하면 된다.
특별한 이유가 없다면 로그인 셸은 기본으로 설정된 bash
를 사용하도록 하자.
터미널과 셸은 무슨 관계일까?
터미널
이란, 컴퓨터의 입출력만을 담당하는 전용 하드웨어를 말한다. 입력 장치인 키보드와 출력 장치인 모니터로 구성되며, 데이터 센터에는 간혹 입출력 기능만 갖춘 간이 단말기(dumb terminal)가 있다.
하지만 현재 리눅스를 다룰 때 하드웨어 터미널을 사용하는 경우는 거의 없기에 소프트웨어로 구현한 터미널 에뮬레이터
가 사용된다. 이는 리눅스, 윈도, 맥 등에서 애플리케이션으로 동작한다.
운영 체제 별
터미널 에뮬레이터
- Windows - PuTTY, Tera Term
- macOS X - terminal, iTerm2
- Linux - GNOME Terminal, Konsole
터미널 에물레이터
와 셸
은 완전히 다른 소프트웨어이니 혼동해서는 안된다.
예를 들어 윈도에서 리눅스로 원격 로그인하면 터미널 에뮬레이터
는 윈도 머신에서 돌아가며, 셸
은 리눅스 머신에서 돌아간다.
터미널 에뮬레이터
는 입출력 화면을 제공만 하는 소프트웨어라는 것을 기억해두자.
소프트웨어 라이센스?
- 소프트웨어 라이센스라 하면 '동시에 몇 대에 설치 가능', '무단 복제 및 배포 금지' 같은 제한 사항이 떠오른다.
리눅스 같은 오픈 소스 소프트웨어도 사용자가 지켜야 할 사항이 있다. 일반적인 유료 소프트웨어와는 다소 다른 형태의 라이센스를 가지는데, 리눅스 커널은 GNU GPL이라는 라이센스를 채택하고 있다. 이 라이센스에 따라 사용자가 프로그램을 무료로 사용할 수 있으며 복제하거나 변경해서 프로그램을 자유롭게 배포할 수 있다. 하지만 GNU GPL을 채용한 소프트웨어를 복제하거나 변경해서 배포할 때는 반드시 동일한 라이센스(GNU GPL)로 배포해야 하며, 이때 파생물의 소스 코드도 함께 배포해야 한다.
리눅스를 사용하는 개인에게는 이러한 라이센스가 무척 자유롭게 느껴지지만, GNU GPL은 파생물의 소스 코드도 공개해야 한다는 강력한 제약이 있으므로 소스 코드를 공개하고 싶지 않은 기업은 주의해야 한다.
GNU GPL보다 관용적인 라이센스로는 Apache, BSD, MIT가 있다. 이들은 GNU GPL처럼 프로그램의 복제나 변경이 가능할 뿐만 아니라 소스 코드를 공개하지 않고도 파생물을 배포할 수 있다.