Linux/리눅스 실무의 이해

02-04-01 셸(Shell)

바우네 2022. 1. 17. 18:00
반응형

02-04 셸(Shell)

셸의 이해

셸의 개념

  1. 셀의 일반적 정의
    • Shell은 사용자가 커널의 서비스 기능을 사용할 수 있도록 하기 위한 통로 또는 사용자 인터페이스
    • Shell은 명령줄 인터페이스 방식(CLI: Command-Line Interface)과 그래픽 유저 인터페이스(GUI: Graphical User Interface)으로 구분된다. 리눅스에서는 주로 CLI방식을 사용한다.
  2. 리눅스 셸의 역사
    • 1971년, 최초 버전의 유닉스에 도입된 최초 유닉스 셸은 캔 톰프슨(Kenneth Lane Thompson)이 작성한 톰프슨 셸(Thompson shell)이다.
    • 1977년, 유닉스 버전 7에 포함된 기본 유닉스 셸은 본셸(Bourne shell, sh)이며 AT&T 벨 연구소의 스티븐 본(Stephen Bourne)이 개발했다.
    • 1970년대 후반, 캘리포니아 버클리 대학의 빌 조이(Bill Joy)가 C언어를 기반으로 강력한 셸 프로그래밍 기능을 가진 C셸을 개발했다.
    • 1983년대, 벨 연구소의 데이비드 콘(David G. Korn)이 본셸과 하위 호환하면서 벨 연구소의 사용자들의 요청하였던 C셸의 수많은 기능을 포함한 콘셸(Korn shell)을 개발하였다.
    • 자유 소프트웨어 진영에서 특허권이 없는 셸을 추구하였고 그 당시 인기 있던 셸과 본셸을 개선하여 bash셸(Bourne Again Shell)이 등장하였다. 리눅스 시스템에는 다양한 셸이 포함되었지만 기본 셸은 bash이다.
  3. 리눅스 셸의 특징
    • 사용자로부터 명령어를 입력받고 해석하여 내장 및 외장 명령어를 처리하는 대화형 사용자 인터페이스이다.
    • 사용자가 직접 커널에게 명령을 내리는 것은 어렵기 때문에 셸을 통해서 쉽게 파일 관리, 프로세스 관리, 배치 프로세싱, 성능 모니터링, 환경 설정 등 커널의 기능을 사용할 수 있다.
    • 셸은 특별한 방식으로 작성된 응용 프로그램이 아니라 일반 응용 프로그램과 같이 커널이 제공하는 시스템 콜을 통해 구현되었다. 즉 사용자가 커널에게 쉽게 명령을 내릴 수 있는 목적으로 만들어진 기본 탑재 응용 프로그램이다.

셸의 유형

구분 설명
본셸계열 sh
(bourne shell)
-1977년 스티븐 본 개발
-1971년 유닉스 최초의 셸이었던 톰프슨 셸을 대체하였던 유닉스 버전 7의 기본 유닉스 셸인 본셸은 유닉스의 기본 셸로서 오랫동안 인기를 누림
ksh
(korn shell)
-1983년 데이비드 콘 개발
-본셸과 호환이 되며 명령어 히스토리(history) 기능과 별칭(alias) 기능, 작업 제어 기능이 추가되었고 명령행 편집 기능을 제공
bash
(bourne again shell)
-1989년 브라이언 폭스 개발
-리눅스에서 가장 많이 사용하는 셸이며 GPLv3 라이선스를 따름
-리눅스, macOS, Windows 등 다양한 운영체제에 이식됨
-bash의 명령어 문법은 sh와 호환되며 ksh와 csh에서 많은 영향을 받아 명령 히스토리, 디렉터리 스택, 명령어 치환, 명령어 자동완성 기능 등을 제공
C셸계열 csh
(C shell)
-1978년 빌 조이 개발
-C언어를 기반으로 강력한 프로그래밍 기능을 제공하고 히스토리, 별명, 직업 제어 등의 기능을 제공
tcsh
(TC shell)
-1981년 켄 그리어 개발
-티넥스(Tenex) 시스템의 명령줄 완성 기능과 명령줄 편집 기능의 영향을 받아 tcsh가 개발되었고 csh와 호환

셸의 설정 및 확인

  1. 현재 셸의 확인
    • 환경 변수 SHELL을 통해 현재 로그인한 사용자의 셸을 확인할 수 있다.
    •  
  2. 시스템이 지원하는 셸 목록 확인: chsh -l(--list-shells)
    • chsh 명령어의 -l, --list-shells 옵션을 사용하여 시스템이 지원하는 셸 목록을 확인할 수 있다.
    •  
  3. 시스템이 지원하는 셸 목록 확인 2: cat /etc/shells
    • 파일을 확인하는 방법으로 cat 명령어 이용
    •  
  4. 셸의 변경: chsh -s /bin/csh
    • chsh 명령어의 -s 옵션을 사용하여 셸을 변경할 수 있다.
    • 설치되지 않은 셸은 없다는 메시지, 있는 셸은 'Shell changed'라고 변경된다.
  5. 특정 사용자의 셸 확인: cat /etc/passwd | grep 사용자ID
    • /etc/passwd 파일의 7번째 필드에 해당 사용자의 셸이 무엇인지 확인할 수 있다. 원하는 셸만 필터링하기 위해 grep 명령어를 활용한다.
  6. 환경변수를 통한 설정 확인
    1. 시스템 정보
      1. HOSTNAME: 시스템의 호스트 명
      2. OSTYPE: 실행 중인 시스템의 운영체제 유형에 대한 정보
      3. DISPLAY: X윈도우 트래픽을 처리할 X디스플레이 서버의 위치
      4. PATH: 실행 파일이 위치한 디렉터리 집합
      5. LANG: 셸 사용시 기본으로 지원되는 언어
    2. 셸 정보
      1. PS1: PS는 Prompt Statement 또는 Prompt String의 약자이며 그중 PS1은 기본 프롬프트 표시명
      2. PS2: PS2는 하나의 명령어를 여러 줄로 입력할 때 표시하는 프롬프트 표시 명
      3. SHELL: 로그인한 셸
      4. HISTFILE: history 정보가 저장되어 있는 파일 경로
      5. HISTFILESIZE: history 파일의 크기
      6. HISTSIZE: history 파일의 명령어 개수
    3. 사용자
      1. UID: 로그인한 사용자의 ID
      2. USER: 로그인한 사용자의 계정명
      3. HOME: 로그인한 사용자의 홈 디렉터리
      4. PWD: 로그인한 사용자의 현재 작업 디렉토리
    4. 응용 프로그램
      1. TERM: 로그인한 사용자의 터미널 종류
      2. MAIL: 로그인한 사용자의 수신 메일이 저장된 경로
  7. 환경변수를 통한 환경설정 예제

셸의 시작과 종료

  1. 로그인 셸과 비로그인 셸
    • 로그인 셸(Login Shell)은 사용자가 userid와 passwd를 입력하여 셸에 진입하는 방식을 뜻한다. 
    • 비로그인 셸(Non-Login Shell)은 말 그대로 로그인 없이 셸을 실행하는 것을 말한다. 가령 이미 셸에 로그인한 상태에서 bash 명령어를 사용하여 셸을 다시 실행하거나 X 윈도우에서 터미널을 실행하는 것 등이 이에 해당한다.
  2. 인터렉티브 셸과 비인터렉티브 셸
    • 인터렉티브 셸(Interactive Shell)은 사용자가 대화형으로 셸을 통해 명령을 입력하고 결과를 받을 수 있는 상태의 셸을 말한다.
    • 비인터렉티브 셸(Non-Interactive Shell)은 셸 스크립트에서 셸을 실행하는 경우이다. 가령 스크립트 첫 줄에 #!/bin/bash를 기입하면 스크립트를 해석할 때 #! 다음에 나오는 경로의 셸을 실행한다.
  3. 리눅스 셸의 시작
    • 로그인 셸 유무와 인터렉티브 셸 유무에 따라 읽어 들이는 환경 설정 파일이 다르다.
    • 로그인 셸인 경우 시스템 전역 설정 파일인 /etc/profile과 /etc/profile.d/*을 읽어 실행하고 각 사용자별 실행 파일인 ~/.bash_profile이나 ~/.bash_login 그리고 ~/.profile 순서대로 먼저 존재하는 파일의 설정을 읽어 들여 적용 및 실행한다.
    • 로그인 셸이 아니라면 인터랙티브 셸 유무를 확인한다. 인터렉티브 셸인 경우 시스템 전역 설정 파일인 /etc/bashrc 파일을 읽어 들이고 사용자 설정 파일인 ~/.bashrc를 실행한다.
    • 인터렉티브 셸 또한 아니라면 환경변수 $BASH_ENV에 설정된 스크립트를 source 명령어를 통해 실행한다.
  4. 리눅스 셸의 종료
    • logout 명령, exit 명령, 혹은 Ctrl+D 조합키를 통해 로그아웃을 하면 사용자용 ~/.bash_logout 설정 파일이 실행된다.
  5. 리눅스 셸의 설정 파일
    • 시스템 설정 파일
      • /etc/profile: 시스템 전역으로 설정할 수 있는 셸 설정 파일이다.
      • /etc/profile.d/*: 사용자가 로그인할 때 /etc/profile.d 디렉터리 안에 있는 모든 셸 스크립트를 실행한다.
      • /etc/bashrc: 시스템 전역의 성격을 갖고 있으며 셸에서 또 다른 셸을 실행하는 비로그인 셸을 실행할 때마다 로드되는 파일이다.
    • 사용자 설정 파일
      • ~/.bash_profile, ~/.bash_login:
        • 사용자가 로그인할 때마다 실행된다. 개별 사용자마다 설정이 필요한 내용이 있을 때 이 파일에 기재한다.
        • 한 번 로그인되면 로그아웃될 때까지 유지된다.
        • 만약 설정이 변경됐다면 source 명령어를 통해 바로 반영된다.
      • ~/.profile
        • 사용자가 시스템에 로그인할 때마다 실행된다.
        • 주로 bash와는 직접 관련 없는 사항을 기재한다.
      • ~/.bashrc 
        • 비로그인 셸에서 실행된다
        • 즉 로그인한 상태에서 새 터미널을 열 때마다 이 파일이 로드된다.
        • 보통 alias 설정이나 함수를 저장한다.
      • ~/.bash_logout
        • 로그인한 셸을 로그아웃할 때마다 실행하는 설정 파일이다.
        • 꼭 필요한 파일은 아니지만 사용자 계정의 임시 파일으르 제거하는 등의 사용자 관리 목적으로 유용하게 사용할 수 있다.

셸의 기능

  1. 자동완성 기능(bash-completion)
    • 사용자의 입력을 줄이기 위해 입력한 문자와 매칭되는 명령 후보를 자동으로 보여준다.
    • 가령 현재 경로에 .profile이라는 파일이 있을 때 [cat .p]까지만 입력하고 [TAB]을 입력하면 현재까지 입력한 스트링과 매칭되는 파일명이 유일할 경우 바로 완성된다.
    • 매칭되는 파일명이 많이 있는 경우 [TAB]을 여러 번 눌러 각 후보를 확인한다.
  2. 히스토리 기능
    • 사용자가 입력한 명령어는 지정한 개수만큼 보관되고 저장한 명령어를 열람하거나 특정 명령어를 실행할 수 있다.
    • 저장된 명령어 확인은 [history]이다.
    • 명령어를 실행하기 위해서는 [! 번호]로 사용한다.
    • 사용자가 입력한 명령어는 홈 디렉터리의 .bash_history 파일에 저장되므로 사용자가 로그아웃하여도 히스토리는 유지된다.
    • 지금까지 입력했던 명령어 이력을 지우기 위해서는 -c 옵션을 사용한다.(아래 그림 참조)
    • 바로 직전 명령어를 실행하는 것은 [!!]이다.
    • 가장 최근 3개의 히스토리만 보고 싶을 경우는 [history 3]을 입력한다.
  3. alias 기능
    • 입력하기 복잡하거나 기억하기 어렵거나 자주 사용하는 명령어는 alias로 별칭을 만들면 손쉽게 입력할 수 있다.
    • 가령 /etc/passwd 파일을 자주 열람하는 사용자가 있다면 아래와 같이 'show-me-passwd'라는 alias를 만들어 사용하면 편리하다.
    • 이미 지정된 alias를 확인하려면 간단하게 'alias'라고 입력한다. alias를 해제하려면 'unalias' 명령어를 사용한다.
    •  
  4. 셸 키보드 단축키
    • 키보드 단축키를 이용해 셸의 화면, 커서의 움직임, 텍스트의 복사와 붙이기 그리고 삭제를 할 수 있다.
    • 구분 단축키
      화면 제어하기 Ctrl+L: 화면을 모두 지움
      Ctrl+S: 화면의 출력을 멈춤
      Ctrl+Q: Ctrl+S로 멈췄던 화면을 다시 재개함
      커서 움직이기 Ctrl+A: 줄의 맨 앞으로 이동
      Ctrl+E: 줄의 맨 끝으로 이동
      Alt+B: 왼쪽으로 한 단어 이동
      Ctrl+B: 왼쪽으로 한 글자 이동
      Alt+F: 오른쪽으로 한 단어 이동
      Ctrl+F: 오른쪽으로 한 글자 이동
      자르고 붙이기 Ctrl+W: 커서 위치 이전의 단어를 잘라 클립보드에 복사함
      Ctrl+K: 커서 위치 이후의 줄을 잘라 클립보드에 복사함
      Ctrl+U: 커서 위치 이전의 줄을 잘라 클립보드에 복사함
      Ctrl+Y: 클립보드의 내용을 붙여넣음
      텍스트 삭제하기 Ctrl+D: 커서 위치의 글자를 삭제
      Alt+D: 현재 커서 이후의 한 단어 삭제
      Ctrl+H: 커서 이전의 글자 삭제
  5. 명령어 치환 기능(Command substitution)
    • 명령어의 실행 결과를 명령어의 인자로 바로 넘길 수 있는 기능이다. 명령어를 아래와 같이 역따옴표(`command`)나 $(command) 형식으로 작성하면 명령어 치환 기능이 수행된다.
    • 역따옴표는 [Esc] 아래 키 [` `]이다.
  6. 표준 입출력 기능
    • 리눅스 커널은 사용자로부터 기본으로 입력 받을 장치와 사용자에게 결과를 출력할 장치라는 개념을 통해 사용자의 입력을 프로그램에게 전달하고 프로그램의 결과를 사용자에게 보여준다.
    • 구분 약어 파일디스크립터 설명
      표준 입력
      (standard input)
      stdin 0 프로그램에게 데이터를 전달할 때 사용하는 기본 장치를 의미
      기본 표준 입력은 키보드로부터 받음
      표준 출력
      (standard output)
      stdout 1 프로그램의 출력을 표시한 기본 장치를 의미
      기본 표준 출력은 모니터로 설정되어 있음
      표준 에러
      (standard error)
      stderr 2 프로그램에서 오류가 발생했을 때 출력할 기본 장치를 의미
      기본 표준 에러는 모니터로 설정되어 있음
  7. 리다이렉션 기능
    • 프로그램의 표준 입력 및 표준 출력을 다른 장치로 재지정하는 것을 말한다. 표준 출력과 관련하여 '>', '>>'가 있고, 표준 입력과 관련하여 '<', '<<'가 있다.
    • 종류 설명
      > 프로그램의 출력을 표준 출력으로 변경한다.
      >> 프로그램의 출력을 표준 출력에서 지정한 출력으로 변경하고 추가한다.
      < 프로그램의 입력을 표준 입력에서 지정한 입력으로 변경한다.
      << 프로그램의 입력을 여러 줄 받을 때 사용하며 지정한 문자열을 입력하면 입력이 종료된다.
  8. 파이프 기능
    • 여러 프로그램의 기능을 하나의 명령줄로 효과적으로 구성할 수 있도록 프로그램의 출력 결과를 또 다른 프로그램의 입력으로 전달할 수 있는 프로세스간 통신 기술(Inter Process Communication)이다.
    • '|'를 통하여 파이프 기능을 사용할 수 있고 파이프를 중첩하여 사용할 수도 있다.
    • 명령어의 출력이 한 화면을 넘어간다면 파이프를 통해 그 결과를 'less' 명령어로 넘겨 마우스 스크롤이나 키보드로 결과를 살펴볼 수 있다.
    • 'tee' 명령어는 파일명을 지정하면서 동시에 표준 출력으로도 보낼 수 있다.
  9. 그룹 명령 기능
    • 제어 연산자(control operator)인 ';'와 '||' 그리고 '&&'를 통해 한 번에 여러 개의 명령어를 입력할 수 있다.
    • ';'는 나열한 순서대로 명령어를 실행하고자 할 때 사용한다.
    • '||'은 앞의 명령어의 실행이 성공하면 그 결과를 출력하고 실패하면 그 다음 명령어를 실행한다. '||'은 여러 번 사용할 수 있다. '||'은 'or' 연산자이다.
    • '&&'은 앞의 명령어의 실행이 성공한 경우에만 다음 명령어를 실행한다. 'and' 연산자이다.
    • ( )를 사용하여 명령어 그룹의 출력 결과를 파일로 리다이렉션할 수도 있다.
    • 위 예로서 (date; pwd; ls) > result.txt
  10. 작업 제어 기능(Job Control Command)
    • 셸에서 실행하는 프로세스를 job 혹은 작업이라고 부른다.
    • 작업은 foreground, background, Stopped의 3가지 상태가 있다.
    • 작업을 백그라운드로 실행할 때 '&'를 사용한다.
    • 작업 간 전환을 위해 'fg', 'bg' 명령을 사용한다.
    • 현재 셸에서 실행한 작업의 목록은 job으로 알 수 있다.
  11. 산술 논리 연산 기능
    • expr 명령어를 통해 산술, 논리 연산을 수행할 수 있다.
    • expr 명령어에 산술 논리 연산 시 연산자와 피연산자는 공백으로 반드시 구분되어야 한다.
    • expr를 위한 기호가 특수문자에 해당하면 \, " ", ' ' 등을 사용해야 한다.
    • '|'은 OR 논리 비교를 수행한다. 앞의 피연산자가 0이거나 ' '이면 뒤의 피연산자를 출력한다. 그렇지 않으면 앞의 피연산자를 출력한다.
    • '&'는 'AND' 논리 비교를 수행한다. 앞 또는 뒤의 피연산자가 0이거나 ' '이면 0을 리턴한다. 그렇지 않으면 앞의 피연산자를 출력한다.
  12. 프롬프트 제어 기능
    • 환경변수 PS1, PS2, PS3, PS4를 통해 셸 프롬프트를 변경할 수 있다. 
    • export PS1="dollar" 명령으로 프롬프트를 'dollar'로 변경할 수 있다.
  13. 확장된 내부 명령어
    • 외부 명령어가 아닌 셸 자체적으로 수행 가능한 빌트인(built-in) 명령어, 즉 내부 명령어를 다양하게 제공한다.

셸과 메타문자

  1. 하나의 명령은 명령어와 명령어 인자 그리고 옵션과 옵션 인자로 구성
  2. 공백으로 구분
  3. 메타문자: 명령어 인자와 옵션 인자 등을 전달하기 전에 특별히 해석하는 문자

 

반응형

'Linux > 리눅스 실무의 이해' 카테고리의 다른 글

02-04-03 셸 스크립트의 조건문  (0) 2022.01.21
02-04-02 셸 프로그래밍  (0) 2022.01.20
02-03 X 윈도우  (0) 2022.01.15
02-02-03 파일 시스템의 이해  (0) 2022.01.14
02-02-02 Systemd  (0) 2022.01.12