#####. 셸
###. 셸의 이해
#. 셸의 개념
+. 일반적인 셸의 정의
- 셸은 사용자가 커널의 서비스 기능을 사용할 수 있도록 하기 위한 통로 또는 사용자 인터페이스
- 셸은 명령줄 인터페이스 방식 CLI (Command Line Interface)과 그래픽 유저 인터페이스 GUI 방식으로 구분
+. 리눅스 셸의 역사
- 71년 최초 버전의 유닉스에 도입된 셸은 켄 톰프슨이 작성한 톰프슨 셸
- 77년 유닉스 버전 7에 포함된 기본 유닉스 셸은 본셸이며, AT&T 벨 연구소의 스티븐 본이 개발
- 70년 후반 버클리 대학 빌 조이가 C 언어를 기반으로 강력한 셸 프로그래밍 기능을 가진 C셸을 개발
- 83년 벨 연구소의 데이비드 콘이 본셸과 하위 호환하면서 벨 연구소의 사용자들이 요청하던 C셸의 기능을 포함한 콘셸을 개발
- 자유 소프트웨어 진영에서 특허권이 없는 셸을 추구하였고 그당시 인기였던 셸과 본셸을 개선하여 bash(Bourne Again Shell)가 등장. 리눅스 시스템에는 다양한 셸이 포함되지만 기본은 bash
- 리눅스 셸의 특징
- 사용자로부터 명령어를 입력받고 해석하여 내장 및 외장 명령어를 처리하는 대화형 사용자 인터페이스
- 사용자가 직접 커널에게 명령을 내리는 것은 어렵기 때문에 셸을 통해 쉽게 파일 관리, 프로세스 관리,배치 프로세싱, 성능 모니터링, 환경설정 등 커널의 기능을 사용할수 잇음
- 셸은 특정한 방식으로 작성된 응용 프로그램이 아니라 일반 응용 프로그램과 같이 커널이 제공하는 시스템 콜을 통해 구현됨, 즉 사용자가 커널에게 쉽게 명령을 내릴 수 있는 목적으로 만들어진 기본 탑재 응용프로그램
#. 셸의 유형
+. 본셸 계열
+. sh, ksh, bash
+. C셸 계열
+. csh, tcsh
#. 셸의 설정 및 확인
+. 현재 셸의 확인
- 환경변수 SHELL을 통해 현재 로그인한 사용자의 셸을 확인 할 수 있음
- 시스템이 지원하는 셸 목록 확인 1
: chsh -l
- 시스템이 지원하는 셸 목록 확인 2
: cat /etc/shells
- 셸의 변경
: chsh 명령어의 -s 옵션을 사용하여 가능
- 특정 사용자의 셸 확인
: /etc/passwd 파일의 7번째 필드에 해당 사용자가 사용하는 셸이 무엇인지 기입되어있음
#. 환경변수를 통한 설정확인 ==> echo $OSTYPE
구분 | 환경변수 | 설명 |
시스템정보 | HOSTNAME | 시스템의 호스트명 |
OSTYPE | 실행중인 시스템의 운영체제 유형에 대한 정보 | |
DISPLAY | X 윈도우 트래픽을 처리할 X 디스플레이 서버의 위치 | |
LANG | 셸 사용 시 기본으로 지원되는 언어 | |
셸 정보 | PS1 | PS는 Prompt Statement 또는 Prompt String의 약자이며 그 중 PS1은 기본 프롬프트 표시명을 뜻함 |
PS2 | 하나의 명령어를 여러줄로 입력할 때 표시하는 프롬프트 표시명 | |
SHELL | 로그인한 사용자의 셸을 보여 | |
HISTFILE | history 정보가 저장되어 있는 파일 경로 | |
HISTFILESIZE | hist의 파일 크기 | |
HISTSIZE | hist의 파일 명령어 개 | |
사용자 | UID | 로그인한 사용자의 UID |
USER | 로그인한 사용자의 계정명 | |
HOME | 로그인한 사용자의 홈 디렉토리 | |
PWD | 로그인한 사용자의 현재 작업 디렉토리의 경로 | |
응용프로그램 | TERM | 로그인한 사용자의 터미널 종류 |
수신한 메일이 저장되어 있는 경로 |
+. 환경변수를 통한 환경설정 예제
- 환경변수값 설정
- export HEKDANCHOO=engineerIS
- echo $HEKDANCHOO
- export PATH=/mypath:$PATH
$$. $는 셸 스크립트에서 변수를 참조할 때 사용하는 특수 문자입니다. $ 다음에 변수 이름을 작성하여 해당 변수의 값을 가져올 수 있습니다.
#. 셸의 시작과 종료
+. 로그인 셸과 비로그인 셸
- 로그인 셸 : 사용자가 userid와 passwd를 입력하여 셸에 진입하는 방식. putty같은 터미널에서 원격 서버에 ssh로 접속하는 행위들
- 비로그인 셸 : 로그인 없이 셸을 실행하는 것을 말함.
+. 인터렉티브 셸/ 비인터렉티브 셸
- 인터렉티브 셸 (Interactive Shell) : 사용자가 대화형으로 명령을 입력하고 결과를 받을 수 있는 상태
- Non-Interactive Shell : .sh스크립트에서 셸을 실행하는 경우. 스크립트 가장 첫 줄에 #!/bin/bash를 기입하면 (셔뱅) #!다음에 나오는 경로의 셸을 실행한다.
+. 리눅스 셸의 시작
- 로그인 셸 유무와 인터랙티브 셸 유무에 따라 읽어들이는 환경파일이 다름
- 로그인 셸인 경우 시스템 전역 설정 파일인 /etc/profile과 /etc/profile.d/*을 읽어 실행하고 각 사용자별 실행 파일인 ~/.bash_profile이나 ~/.bash_login 그리고 ~/.profile 순서대로 먼저 존재하는 파일의 설정을 읽어들여 적용 및 실행함
- 로그인 셸이 아니라면 인터랙티브 셸 유무를 확인. 인터렉티브 셸인 경우 시스템 전역 설정 파일인 /etc/bashrc 파일을 읽어들이고 사용자 환경 파일인 ~/.bash를 실행
- 인터랙티브 셸 또한 아니라면 환경변수 $BASH_ENV에 설정되어 있는 스크립트를 source 명령어를 통해 실행
+. 리눅스 셸의 종료
- logout 명령, exit 명령을 통해 로그아웃을 하면 사용자용 ~/.bash_logout 설정 파일이 실행됨
+. 리눅스 셸의 설정파일
구분 | 설정파일 | 설명 |
시스템 파일 설정 | /etc/profile | 시스템 전역으로 생성할 수 있는 셸 설정 파일 |
/etc/profile.d/* | 사용자가 로그인할 때 /etc/profile.d 디렉토리 안에 있는 모든 셸 스크립트를 실행 | |
/etc/bashrc | 시스템 전역의 성격을 갖고 있으며 셸에서 또 다른 셸을 실행하는 비로그인 셸을 실행할 때 마다 로드되는 파일 | |
사용자 설정 파일 | ~/.bash_prifle ~/.bash_login |
- 사용자가 시스템에 로그인 할 때마다 실행. 개별 사용자마다 설정이 필요한 내용이 있을 때 이 파일에 기재함 - 한 번 로그인이 되면 로그아웃될 때까지 유지됨 - 만약 설정이 변경되었다면 source 명령어를 통해 즉시 반영 가능 |
~/.profile | - 사용자가 시스템에 로그인할 때마다 실행 - 주로 bash와는 직접 련이 없는 사항을 기재 |
|
~/.bashrc | - 비로그인 셸에서 실행됨 - 로그인한 상태에서 새로운 터미널을 열 때마다 이 파일이 로드됨 - 보통 alias 설정이나 함수를 저장 |
|
~/.bash_logout | - 로그인한 셸을 로그아웃할 때마다 실행하는 설정 파일 - 꼭 필요한 파일은 아니지만 사용자 계정의 임시 파일을 제거하는 등의 사용자 관리 목적으로 유용하게 사용할 수 있음 |
###. 셸의 기능
+. 자동완성 기능(bash-completion)
- 사용자의 입력을 줄이기 위해 입력한 문자와 매칭되는 명령 후보를 자동으로 보여줌
- 현재 경로에 .profile이라는 파일이 있을 때 cat .p까지만 입력하고 [TAB]을 누르면 현재까지 입력한 스트링과 매칭되는 파일명이 유일할 경우 바로 자동 완성 시켜줌
- 매칭되는 파일이 여러개면 탭을 여러번 눌러 각 후보를 확인 가능
+. 히스토리(history) 기능
- 사용자가 입력한 명령어는 지정한 개수만큼 보관되고 저장한 명령어를 열람하거나 특정 멸령어를 실행할 수 있음
- 저장한 명령어를 확인하기 위해서는 history명령을 옵션없이 사용하면 됨
- 히스토리 내용 중 리스트 번호를 !의 뒤에 입력하면 그 명령어를 실행할 수 있음
- 사용자가 입력한 명령어는 홈 디렉토리의 .bash_history 파일에 저장되므로 사용자가 로그아웃 하여도 히스토리는 유지
- 지금까지 명령어 이력을 지우기 위해서는 -c옵션을 사용
- 바로 직전 명령어를 실행하기 위해서는 !!를 입력!!!!!
- 최근의 히스토리 n개를 보고 싶을 경우 history n
+. alias 기능
- 입력하기 복잡하거나 기억하기 어렵거나 자주 사용하는 명령어는 alias로 별치을 만들어 사용 가능
- docker container ls -a명령어를 자주 사용한다면 dock.list를 alias 설정을 하면 됨
- 알리아스 해제 방법은 unalias
+. 셸 키보드 단축키
- 키보드 단축키를 이용하여 셸의 화면, 커서의 움직임, 텍스트의 복사와 붙이기 그리고 삭제를 할 수 있음
구분 | 단축키 |
화면 제어하기 | - ctrl + l : 화면을 모두 지움 - ctrl + s : 화면의 출력을 멈춤 - ctrl + q : 멈춘 화면을 다시 재개함 |
커서 움직이기 | - 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 : 커서 이전의 글자 삭제 |
: 위 내용 중 유용해 보이는 것은 ctrl + w, ctrl + y 인듯 하다. 클립보드에 복사된 내용은 자체 리눅스 OS에만 적용된다.
+. 명령어 치환 기능 (Command substitution)
- 명령어의 실행 결과를 명령어의 인자로 바로 넘길 수 있는 기능. 명령어를 아래와 같이 역따옴표나 $() 형식으로 작성하면 명령어 치환 기능이 수행
- tough 명령어를 통해 현재 시각을 파일명으로 갖는 파일 생성
+. 표준 입출력 기능
- 리눅스 커널은 사용자로부터 기본으로 입력 받을 장치와 사용자에게 결과를 출력할 장치라는 개념을 통해 사용자의 입력을 프로그램에게 전달하고 프로그램의 결과를 사용자에게 보여줌
구분 | 약어 | 파일 디스크립터 | 설명 |
표준 입력 | stdin | 0 | - 프로그램에게 데이터를 전달할 때 기본 장치를 의미 - 기본 표준 입력은 키보드로부터 받음 |
표준 출력 | stdout | 1 | - 프로그램의 출력을 표시한 기본 장치를 의미 - 기본 표준 출력은 모니터로 설정되어 있음 |
표준 에러 | stderr | 2 | - 프로그램에서 오류가 발생했을 때 출력할 기본 장치를 의미 - 기본 표준 에러는 모니터로 설정되어 있음 |
- 아래 그림으로 보면 프로세스 A의 표준 입력은 키보드이고, 표준 출력과 표준 에러는 화면으로 설정되어 있음
- echo 명령어에게 문자열 hello를 출력하라고 지시하면 표준 출력 화면인 화면으로 결과가 나타남
- cat 명령어를 옵션 없이 사용하면 표준 입력으로부터 데이터를 기다림. 사용자가 this is stdin 이라고 입력하면 cat은 이 데이터를 받아 표준 출력 화면으로 this is stdin을 출력함. cat을 종료하려면 단축키 crtl + d를 입력
- cat 명령어의 인자로 존재하지 않는 파일을 지정하면 오류메세지가 출력 되는데, 아래 예제와 같이 표준 출력만을 리다이렉션하는 파이프로 sed 명령어를 사용하여 스트링 치환을 적용해 보면 여전히 스트링 치환이 되지 않음을 알수 있고 cat명령어의 오류 메세지는 표준 출력이 아님을 알 수 있음
+. 리다이렉션 기능
- 프로그램의 표준 입력 및 표준 출력을 다른 장치로 재지정하는 것을 말함. 표준 출력과 관련하여 '>', '>>'가 있고 표준 출력 입력과 관련하여 '<','<<'가 있다.
종류 | 설명 |
> | 프로그램의 출력을 표준 출력에서 지정한 출력으로 변경 |
>> | 프로그램의 출력 표준 풀력에서 지정한 출력으로 변경하고 추가 |
< | 프로그램의 입력을 표준 입력에서 지정한 입력으로 변경 |
<< | 프로그램의 입력을 여러 줄 받을 때 사용하며 지정한 문자열을 입력하면 입력이 종료됨 |
- ls -l 의 출력 결과를 listening_file 파일로 표준 출력을 재지정함. cat 파일로 확인해보면 ls 명령어의 출력과 결과가 정상적으로 저장 되어 있음을 확인할 수 있음
- 음악 파일의 재생을 표준 출력이 아닌 오디오 장치로 재지정
: 예 > cat kpop.mp3 > /dev/audio
- 표준 입력을 파일로 재지정하여 sort 프로그램에게 데이터를 전달. sort 프로그램이 전달 받은 데이터를 정렬하여 표준 출력인 화면으로 표시
- cat 명령어의 옵션에 존재하지 않는 파일을 지정하면 에러가 표준 에러로 발생함. 이 에러를 표준 에러에서 파일로 재지정
- 표준 에러의 재지정은 사용자가 스크립트를 실행할 때 에러만을 따로 파일로 저장할 수 있고 화면 출력에는 에러 없이 정보만을 전달할 수 있어 유용
- 프로그램의 에러에 관심이 없을 경우 null장치로 보낼 수도 있음
: no-exist-command 2> /dev/null
- 리눅스 관리자가 어떤 명령어의 실행 결과와 에러를 모두한 파일로 표준 출력을 재지정하고 싶어 할 수 도 있음. 특히 표준 에러를의미하는 파일 디스크립터 2를 '&'를 통해 표준 출력을 의미하는 파일스트립터 1로 재지정하였음
+. 파이프 기능
- 여러 프로그램의 기능을 하나의 명령줄로 효과적으로 구성할 수 있도록 프로그램의 출력 결과를 또다른 프로그램의 입력으로 전달할 수 있는 일종의 프로세스간 통신 기술 IPC(Inter Process Coummunicatin)
- '|' 를 통해 파이프 기능을 사용할 수 있고 아래 예처럼 중첩하여 사용할 수 도 있음
: command 1 | command 2 | command 3
- 아래와 같이 ls -l 명령어의 출력이 한 호면을 넘어간다면 파이프를 통해 그 결과를 less 명령어로 넘겨 마우스 스크롤이나 키보드로 결과를 살펴볼 수 있음
: ls -l | less
+. tee
- 해당 명령어는 표준 입력으로부터 데이터를 읽어 표준 출력으로 출력하거나 또느 ㄴ이와 동시에 파일에 저장할 수 있음
- tee는 표준 출력과 파일 저장을 동시에 수행할 수 있기 때문에 하나의 파이프라인을 양 갈래로 나누어 보낼 수 있음
- tee 명령은 단독으로 사용 가능하고 파일명을 지정한 경우 표준 출력과 파일에 동시에 보낼 수 있음. 또한 다른 프로그램의 출력 결과를 표준 입력으로 받을 수도 있음\
- tee 활용 예
- tee -a 옵션을 추가하면 새로 생성되는 것이 아니라 추가 옵션을 설정 가능
+. 그룹 명령 기능
- 제어 연산자 (control operator)인 ; || &&를 통해 한 번에 여러 개의 명령어를 입력할 수 있음
: ; 는 나열한 순서대로 명령을 실행하고자 할 때 사용
: ||은 앞의 명령어의 실행이 성공하면 그 결과를 출력하고 실패하면 다음 명령어를 실행한다는 뜻
: &&는 앞의 명령어가 성공한 경우만 다음 명령어를 실행. ||과 마찬가지로 여러번 사용 가능 ls 명령어 다음 성공하면 secced를 출력하라는 명령어이다. dirlest는 디렉토리가 아니기 떄문에 failed 라는 명령은 실행하지 않는다.
+. 작업 제어 기능 (Job control Command)
- 셸에서 실행하는 프로세스를 잡, 작업이라 부름
- 작업은 각각 포어그라운드 (foreground), 백그라운드(background), 멈춤(stopped)의 3가지 상태를 갖음
- 작업을 백그라운드로 실행할 때는 &를 사용
- 작업간 전환을 위해 fg, bg 명령을 사용
- 현재 셸에서 실행한 작업의 목록은 jobs 명령어로 알 수 있음
+. 산술 논리 연산 기능
- expr 명령어를 통해 한술, 논리 연산을 수행 할 수 있음
- expr 명령어에 산술 논리 연산 시 연산자와 피 연산자는 공백으로 반드시 구분되어야 함
- 공백을 주지 않으면 연산이 아닌 문자열로 인식
- expr 을 위한 기호가 특수문자에 해당하면 앞쪽에 역 슬래시\, 쌍 따옴표"", 홑 따옴표''를 입력해야 함
- 논리 연산 |은 or의 논리 비교를 수행하여, 앞의 피연산자가 0이거나 공백이면 뒤의 피연산자를 출력함
- 논리 연산 &는 and의 논리 비교를 수행하여, 앞또는 뒤의 피연산자가 0이거나 공백이면 0을 리턴하고 그렇지 않으면 앞의 연산자를 출력
- expr 명령어는 /usr/bin에 위치하지만 bash에서는 내장된 expr을 사용
- expr 명령어는 산순 논리 연산뿐 아니라 스트링 길이 계산, 서브스트링, 스트링 매칭과 같은 스트링 연산과 정규식 계산이 가능
- expr 명령어에 length 옵션을 사용하여 스트링의 길이를 구할 수 있음
+. 프롬프트 제어 기능
- 환경변수 PS1, PS2, PS3, PS4를 통하여 셸 프롬프트를 변경 할 수 있음. 셸 프롬프트를 $ 에서 지정한 값으로 변경 가능
+. 확장된 내부 명령어
- 외부 명령어가 아닌 셸 자체적으로 수행 가능한 빌트인 명령어, 즉 내부 명령어를 다양하게 제공
구분 | 명령어 | 설명 |
입출력 | echo | 변수나 표현식을 표준 출력으로 출력함 |
printf | 형식화된 출력을 수행 $ printf "%s %s/n" hekDanChoo hekDanChoo |
|
read | 변수값을 표준 입력에서 읽어드림 | |
파일 시스템 | cd | 디렉토리를 변경 |
pwd | 현재 디렉토리를 표시 | |
pushd, popd, dirs | 디텍토리를 스택에 푸시, 팝하거나 현재 스택의 목록을 볼 때 사용 | |
변수 | let | 변수에 대해 산술 연산 수행 |
eval | 인자를 명령어로 변환 | |
set | 내부 스크립트의 변수값을 변경 | |
unset | 내부 스크립트의 변수값을 변경 | |
export | 변수에 값을 설정 | |
스크립트 | source | 지정한 파일을 스크립트로 실행 |
exit | 스크립트를 종료함 | |
exec | 프로세스를 실행할 떄 fork하지 않고 셸 자체에서 실행함 |
+. 셸과 메타문자
- 하나의 명령은 명령어와 명령어 인자 그리고 명령어 옵션과 옵션 인자로 구성되어 있고 공백으로 구분함
- 셸이 명령어에게 명령어 인자, 옵션 인자 등을 전달하기 전에 특별히 해석하는 특수문자가 있는데 이를 메타 문자라고 함
기호 | 설명 |
> | 표준 출력 리다이렉션 |
>> | 표준 출력 리다이렉션(데이터 끝에 추가) |
< | 표준 입력 리다이렉션 |
<< | 표준 입력 리다이렉션 (여러 줄 입력) |
* | 파일 매칭을 위한 와일드 카드이며 0개 이상의 글자와 매칭됨 |
? | 파일 매칭을 위한 와일드 카드이며 1개 이상의 글자와 매칭됨 |
[ ] | 파일 매칭을 위한 와일드카드이며 브라켓(bracket) 사이에 열거한 글자들과 매칭 |
'cmd' , $(cmd) | 명령어 치환 기능(command substitution)을 위해 사용 |
| | 파이프 기능을 위해 사용 |
; | 그룹 명령을 위해 사용, 순차적으로 실행 |
|| | 그룹 명령 기능을 위해 사용하며 앞 명령어의 실행 결과가 실패하면 다음 명령어를 실행 |
&& | 그룹 명령 기능을 위해 사용하며 앞 명령어의 실해 결과가 성공하면 다음 명령어를 사용 |
() | 여러 개의 명령어들을 그룹화 할 수 있고 연산자의 우선순위 조절에도 사용 할 수 있음 |
& | 명령어를 백그라운드에서 실행 |
# | 셸은 이 기호에 대하여 아무런 해석도 하지 않음, 명령어에 대한 설명을 하기 위한 주석으로 사용 |
$ | 셸에서 사용하는 변수를 의미,변수가 담고 있는 값을 반환 |
\ | - 탈출 문자이며 해당 기호 다음 특수 문자의 해석을 하지 않도록 셸에게 지시 - 명령어 입력 시 여러줄로 입력하고자 할 때 줄 끝에 입력하기도 함 |
###. 셸 프로그래밍
#. 셸 프로그래밍 개요
+. 셸 프로그래미으이 개념
- 셸 프로그래밍(shell programming)이란 특정 목적을 달성하기 위한 셸 스크립트를 작성하는 활동을 의미하며 셸 스크립팅이라고도 함
- 셸 스크립트란 셸에서 제공하는 여러 명령어를 나열한 일종의 파일. 이 셸스크립트를 실행하면 여러 명령어를 일일이 입력할 필요 없이 한 번에 일련의 명령어를 실행 할 수 있음
- 셸 스크립트를 통해 주기적인 백업, 시스템 모니터링 등 반복 작업을 자동화 할 수 있음
- 셸 스크립트는 프로그래밍 언어에 비해 문법이 간단하여 작성하기 쉽고 빠르게 작성할 수 있음. 또한 인터프리터가 명령어 해석을 바로바로 하기 때문에 디버깅하기 쉬움
+. 셸 스크립트의 형식
- 첫 번째 줄에는 해당 스크립트가 사용할 셸 #!를 통하여 명시
- 두 번째 줄부터는 일련의 명령어를 기술함'
+. #! (shebang)
- 실행 파일은 바이너리 형태이거나 스크립트처럼 텍스트 형태일 수 있는데 프로그램 로드(program loader)는 #! 매직 넘버를 통해 해당 실행파일인지 바이러니인지 스크립트인지 구분할 수 있음
- #! 이후에 실행할 셸 종류를 지정하기 때문에 프로그램 로더는 지정한 셸을 통해 스크립트를 실행 할 수 있게 됨
+. 셸 스크립트의 실행
- 셸 스크립트를 실행할 때 별도의 프로세스로 실행하는 방법과 현재 셸에서 바로 실행하는 방법이 있음
- 별도의 프로세스로 실행하기 위해서는 스크립트 파일의 퍼미션에 실행 권한을 주고 실행함. 이때 현재 경로를 의미하는 ./를 꼭 붙여야 함
+. 셸 스크립트를 실행할 때 ./ 꼭 붙이는 이유
- 셸은 환경변수 PATH에 지정된 경로에서만 실행 파일을 찾기 때문에 꼭 ./ 를 붙여 줘야함
- 실행할 때 셸의 인자로 스크립트 파일 경로를 넘겨서 직접 실행 할 수도 있음
$$. 프로그램 로더 : 하드디스크와 같은 외부 기억장치에서 메모리와 같은 주기억장치에 프로그램을 적재하고 실행하는 역할을 수행하는 시스템 프로그램
$$. 매직 넘버 : 프로그램이 대상을 식별하기 위한 개발자가 지정한 고유의 값, 프로그램 로더는 바이너리인지 스크립트인지 구분하기 위해 파일의 시작이 #!의 Hex값이 0x023, 0x21로 시작하는지 확인
#. 셸 스크립트의 기본 문법
+. 주석
- 주석은 프로그램의 이해를 돕기 위한 설명을 의미, 셸 스크립트에서는 #을 주석으로 사용
+. 변수
- 변수는 스크립트의 동작을 위해 필요한 데이터를 저장하거나 읽어오거나 조작할 수 있는 메모리상 저장공간
- 사용하는 형식은 VAR=value이며 공백을 허용하지 않음, 보통은 변수 이름은 대문자로 표기함, VAR은 변수 이름 value는 변수에 저장될 값
- 다양한 변수의 활용
명령어 | 내용 |
echo "\${HDC}=${HDC}" | 변수 값 출력 |
echo "length=${#HDC}" | 스트링 길이 출력 |
echo ${HDC:offset} echo "offset=${HDC:3}" |
변수의 특정 오프셋 이후를 반환 |
echo ${HDC:+value} echo "\${HDC}=${HDC:+is king}" |
HDC 변수값이 null이 아니면 값을 반환하지만 변수에 할당하지 않음 |
+. 변수의 범위(scope)
- 변수를 선언하면 선언한 셸에서만 유효. 셸을 벗어나면 해당 변수에 접근할 수 없다. 이를 지역(local)변수라 함. 지역 변수를 선언할 떄 VAR=value 형식도 가능하지만 export 명령어를 사용할 수 도 있음. 선언한 변수를 해제할 때는 unset 명령 사용
- 아래 그림을 보면 CLI 명령 줄에 HDC를 abc로 저장하고 셸 스크립트에 hek dan choo를 저장함. 1.2.3.번 순으로 호출 하니 같은 변수 이름 HDC라도 지역 변수마다 다른 값을 가지고 있는 것을 확
+. 위치 매개변수
- 명령줄에 지정된 인자의 위치를 나타내는 특별한 변수. $0은 명령어를 나타내고 $1, $2는 첫 번째 인자와 두번째 인자를 나타냄. $@ 또는 $*은 모든 위치 매개변수를 뜻함
+. $@와 $*의 차이점
- $@은 환경변수 $IFS설정 구분된 구분자를 통해 위치 매개변수를 분리하여 보관
- $*은 모든 위치 매개변수를 하나의 스트링으로 보관
+. echo문
- echo 명령은 스트링을 화면에 출력
- echo 명령에 -e 옵션을 사용하면 \n과 같은 특수문자 사용 가능
- echo 명령에 사용할 수 있는 특수문자
특수문자 | 설명 |
\b | 백스페이스(backspace)를 입력 |
\f | 폼피드(formfeed)를 입력 |
\n | 새로운 줄(newline)을 입력 |
\r | 캐리지리턴(carriage-return)을 입력 |
\t | 탭(tab)을 입력 |
\\ | 백슬래시(backslash)를 입력 |
+. 다양한 조건식
- 두 개의 숫자를 비교하여 더 큰지, 같은지, 작은지 등을 비교할 수 있음
num1 -eq num2 | num1과 num2가 같으면 참 |
num1 -ge num2 | num1이 num2보다 크거나 같으면 참 |
num1 -gt num2 | num1이 num2보다 크면 참 |
num1 -le num2 | num1이 num2보다 작거나 같으면 참 |
num1 -lt num2 | num1이 num2보다 작으면 참 |
num -ne num2 | num1과 num2가 다르면 참 |
!num1 | num1이 참이면 거짓이고 반대로 거짓이면 참 |
num1 -a num2 | num1과 num1을 AND함. 즉 모두 참이어야 |
num1 -o num2 | num1과 num2를 OR함. 즉 둘 중 하나만 참이어도 참 |
- 두 문자열을 비교하여 같은지 다른지 어느쪽이 큰지 또는 길이를 비교할 수 있음
var1 = var2 | var1과 var2가 같으면 참 |
var1 != var2 | var1과 var2가 다르면 참 |
var1 < var2 | var1보다 var2가 크면 참 |
var1 > var2 | var1이 var2가보다 크면 참 |
-n var1 | var1의 길이가 0보다 크면 참 |
-z var1 | var1의 길이가 0이면 참 |
- 파일이 블록 디바이스인지 문자 디바이스인지 디렉토리인지 파일인지 등을 비교할 수 있음
-b file | file이 블록 디바이스이면 참 |
-c file | file이 문자 디바이스이면 참 |
-d | file이 디렉토리이면 참 |
-e | file이 존재하면 참 |
-x | 존재하고 실행 가능하면 참 |
-r | 존재하고 읽기 가능하면 참 |
-w | 존재하고 쓰기 가능하면 참 |
-f | 존재하고 정규파일이면 참 |
-g | Set-GID(Set Group ID bit)가 있으면 |
+. 명령행에서 2가지 비교법
- '[' 와 ']' 사이에서 표현식을 넣어 비교할 수 있음
- tset 명령어 다음에 표현식을 넣어 비교할 수 있음
#. 셸 스크립트의 조건문
+. if 문
- if문의 표현식이 참이면 then 구문의 명령문이 실행 됨. 그렇지 않으면 fi 구문 이후의 명령문이 실행됨. if 구문의 표현식은 '[' 과 ']' 사이에 공백을 둬야 함.
if [표현식]
then
명령문
fi
- if-else문의 표현식이 참이면 then 구문의 명령문을 실행하고 그렇지 않으면 else 구문의 명령문을 실행
if [표현식]
then
명령문
else
명령문
fi
- if-elif-else-fi문은 if 구문의 표현식이 참이면 then 이하의 명령문을 실행하고 그렇지 않으면 elif 구문 이하의 표현식이 참인지 확인. 참이면 then 구문 이하의 명령문을 실행하고 그렇지 않으면 else 구문 이하의 명령문을 실행
if [표현식]
then
명령문
elif [표현식]
then
명령문
else
명령문
fi
- if-then-else-if-then-fi=-fi문 (중첩 if문)은 if의 표현식이 참이면 then 이하의 명령문을 실행하고 그렇지 않으면 else이하의 구문을 실행. 그리고 그 명령문은 동일한 if 구문을 중첩하여 실행
if [표현식]
then
명령문
else
if [표현식]
then
명령문
fi
fi
- if 구문에서 첫 번쨰 인자가 "cool"이라면 then 이하의 구문 "cool wind"를 화면에 출력. 그렇지 않다면 첫 번째 인자가 "warm"과 같은지 확인하고 같아면 then 이하의 구문 "warm wind"를 출력. 그렇지 않으면 "Not warm wind"를 출력
$$. 위의 ["$1"="warm"]을 사용하니 에러가 났다. [ "$1" = "warm" ] 이렇게 공백을 주니 에러 없이 성공!
+. case 문
- case문은 $변수와 상응하는 패턴의 명령문을 실행
case $변수 in
패턴 1)
명령문
패턴 2)
명령문
*)
명령문
esac
- $HDC가 'MON'이라면 "Full backup"을 출력하고 Tue, Wed, Thu, Fri 중 하나라면 "Partial backup"을 출력. Sat, Sun 인경우 No backup을 출력 그외라면 Error를 출력
#. 셸 스크립트의 반복문
+. for문
- 변수에 값1을 할당하고 명령문을 실행함. 변수에 값2를 할당하고 명령문을 실행. in 구문 이하의 값을 모두 순차저긍로 할당할 떄마다 명령문을 실행
for $변수 in 값1, 값2
do
명령문
done
- 변수 i에 1을 할당하고, "Loop ... numver $i"를 출력하고 변수 i에 2를 할당하고 "Loop ... number $i"를 출력함. 순차적으로 i에 3,4,5를 할당하고 마찬가지로 echo문을 실행
+. while 문
- 표현식이 참일 동안 do와 done 사이의 명령문을 실행. 표현식이 거짓일 경우 반복문을 종료
while 표현식
do
명령문
done
- INPUT_STRING 변수에 bye가 입력 될 때까지 "You typed : $INPUT_STRING"을 출력. bye가 입력되면 반복문이 종료
+. until문
- 표현식이 만족할 때까지 명령문을 실행
until 표현식
do
명령문
done
- 변수 hdc가 6보다 클 떄까지 "Welcome $hdc times"를 출력
+. select문
- 메뉴 중 숫자로 항목을 선택하고 그에 대응하는 명령어를 수행하기 위한 반복문
select $변수 in 메뉴1 메뉴2 메뉴3.....
do
수행할 명령어
done
- list 또는 whereYouAre 메뉴 항목을 숫자로 선택하면 해당 명령어를 실행하고 quit 메뉴 항목의 숫자를 선택하면 셸을 종료
#. 셸 스크립트의 함수
+. 함수 구문 문법
- 함수의 정의는 function 지시어를 통해 함수 이름을 선언하고 함수가 수행할 명령문을 기술함.
function 함수이름
{
명령문
}
- 함수의 호출은 함수 이름을 명시하여 호출
#!/bin/bash
함수 이름
#. 셸 스크립트의 부분 문자열 제거
+. 스트링과 패턴을 비교하여 매칭된 문자열을 소거하는 4가지 방법
${string#pattern} | 맨 앞부터 패턴과 가장 짧게 매치된 문자열을 지움 |
${string##pattern} | 맨 앞부터 패턴과 가장 길게 매치된 문자열을 지움 |
${string%pattern} | 맨 뒤부터 패턴과 가장 짧게 매치된 문자열을 지움 |
${string%%pattern} | 맨 뒤부터 패턴과 가장 길게 매치된 문자열을 지움 |
- 문자열의 앞부터 A로 시작해서 1로 종료하는 패턴 중 가장 짧은 매칭을 삭제
- 문자열의 앞부터 A로 시작해서 1로 종료하는 패턴중 가장 긴 매칭을 삭제