셸 Shell
1. 셸의 이해
1) 셸의 개념
- 일반적인 셸의 정의
- 사용자가 커널의 서비스 기능을 사용할 수 있도록 하기 위한 통로 또는 사용자 인터페이스.
- 명령줄 인터페이스 방식 CLI 과 그래픽 유저 인터페이스 방식 GUI로 구분
- 주로 CLI 방식으로 사용 - 리눅스 셸의 역사
- 71년 유닉스에 도입된 최초의 셸, 톰프슨 셸
- 77년 기본 유닉스 셸, 본셸. AT&T의 벨연구소 스티븐 본이 개발.
- 70년대 후반 빌조이가 C언어를 기반으로 개발한 C셸
- 83년 C셸의 기능을 포함한 콘셸을 개발
- 자유 소프트웨어 진영에서 bash 셸 등장. 리눅스의 기본 셸. - 특징
- 사용자로부터 명령어를 입력받고 해석하여 처리하는 대화형 인터페이스
- 셸을 통해서 쉽게 파일관리, 프로세스 관리, 배치 프로세싱, 성능 모니터링, 환경 설정 등 커널의 기능을 사용할 수 있음.
- 일반 응용프로그램과 같이 커널이 제공하는 시스템 콜을 통해 구현.
- 사용자가 커널에게 쉽게 명령을 내릴수있게 만든 기본 탑재 응용 프로그램.
2) 셸의 유형
본셸계열 - sh (bourne shell), ksh (korn shell), bash (bourne again shell)
C셸계열 - csh (C shell), tcsh (TCshell)
3) 셸의 설정 및 확인
- 현재 셸의 확인
환경변수 SHELL을 통해 로그인한 사용자 셸 확인
$echo $SHELL
/bin/bash - 시스템이 지원하는 셸 목록 확인 -1
chsh 명령어의 -I 옵션을 사용하여 시스템이 지원하는 셸목록을 확인할 수 있음
$ chsh -I
/bin/sh
/bin/bash
/sbin/nologin
... - 시스템이 지원하는 셸 목록 확인 -2
/stc/shells 파일에 시스템이 지원하는 셸 목록이 기록되어 있어 이 파일을 확인.
$cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
... - 셸의 변경
chsh 명령어의 -s 옵션을 사용하여 셸을 변경
$chsh -s /bin/csh
Changing shell for trancis
Password:
Shell changed - 특정 사용자의 셸 확인
$cat /etc/passwd | grep francis
francis:x500:500:francis:/home/francis:/bin/csh - 환경변수를 통한 설정 확인
set 명령어로 확인
$set
DISPLAY=:0.0
HISFILE=/home/francis/.bash_history
HISFILESIZE=1000
HOME=/home/francis
... - 환경변수를 통한 설정 예제
:echo 명령어와 printenv 명령어를 통해 환경변수값 확인
$echo $HOME
/home/francis
$printenv PWD
/home/francis
export 명령어를 통해 환경변수 추가 정의
$export MYENV=this-is-my-environment-variable
$echo $MYENV
this-is-my-environment-variable
export 명령어를 통해 기존 환경변수의 값에 새로운 값 추가
$export PATH=/mypath:$PATH
$echo $PATH
/mypath:/usr/lib/qt-3.3/bin:/usr/local/bin.....
4) 셸의 시작과 종료
- 로그인 셸과 비로그인 셸
- 로그인 셸. userid와 passwd 입력하여 셸에 진입하는 방식
- 비로그인 셸. 로그인 없이 셸을 실행하는 것. bash명령어를 사용해 셸을 사용하거나, x윈도우 터미널 실행. - 인터랙티브 셸과 비 인터렉티브 셸
- 인터랙티브 셸. 대화형으로 셀을 통해 명령을 입력하고 결과를 받을수 있는 상태의 셸.
- 비 인터랙티브 셸. 셸 스크립트에서 셸을 실행하는 경우. #!/bin/bash 기입하면 #! 다음의 경로 셸 실행. - 리눅스 셸의 시작
- 로그인 셸 유무와 인터렉티브 셸 유무에 따라 읽어들이는 환경설정파일이 다름.
- 로그인 셸의 경우 시스템 전역 파일인 /etc/profile과 /etc/profile.d/* 읽어 실행.
각 사용자별 실행파일인 ~/.bash_profile, ~/.bash_login 그리고 ~/.profile 순으로 먼저 존재하는 파일 설정 읽어 실행
- 로그인 셸이 아니라면 인터렉티브 셸 유무 확인.인터렉티브 셸인 경우
시스템 전역 설정파일인 /etc/bashrc 파일을 읽어 사용자 설정파일인 ~/.bashrc 실행
- 인터랙티브 셸도 아니면 환경변수 $BASH_ENV 설정되어 있는 스크립트를 source 명령어 통해 실행. - 리눅스 셸의 종료
- logout, exit 명령. Ctrl + D 조합키.
사용자용 ~/.bash_logout 설정파일 실행. - 리눅스 셸의 설정파일
시스템 설정 파일
/etc/profile , /etc/profile.d/*, /etc/bashrc
사용자 설정파일
~/.bash_profile, ~/.bash_login, ~/.profile, ~/.bashrc, ~/.bash_logout
5) 셸의 기능
- 자동완성 기능(bash-completion)
현재 경로에 입력하려는 문자와 매칭되는 파일명이나 명령 후보를 자동으로 보여줌. TAB 입력하여 후보 확인. - 히스토리 기능
- 사용자가 입력한 명령어가 보관이 됨. 저장 명령어를 열람하고 실행 가능.
$history
- 특정 명령어를 실행하기 위해 열람한 번호를 !와 붙여 사용
!2
- 히스토리 지우기
$history -c
- 직전 명령어 입력
$!!
- 최근 3개 히스토리
$history 3 - alias 기능
- alias 설정
$alias show-me-passwd='cat /etc/passwd'
- alias 해제
$unalias show-me-passwd - 셸 키보드 단축키
- 여러 텍스트 제어 단축키 제공 - 명령어 치환 기능 Command substitution
- 명령어의 실행 결과를 명령어의 인자로 넘기는 기능
$(command) 또는 'command'
- touch 명령어를 통해 현재시각을 파일명으로 갖는 파일 생성
$touch "$(date)" - 표준 입출력 기능
- 사용자의 입력을 프로그램에 전달하고 결과를 보여줌.
표준입력 stadin 0 데이터 입력 기본장치
표준출력 stdout 1 출력 기본장치
표준에러 stderr 2 오류발생시 출력 기본장치 - 리다이렉션 기능
-표준 출력과 > , >>
-표준 입력과 < , <<
- ls -l 출력결과를 listing-file 파일로 표준출력 재지정.
$ls -l > listing-file
- 표준입력을 파일로 재지정하여 sort 프로그램에게 데이터 전달
$sort < listing-file
- cat 명령어의 옵션에 존재하지 ㅇ낳는 파일 지정하면 에러가 표준에러로 발생
$cat no-file 2>errorsfile
- tmp 폴더에 'pulse'로 시작하는 파일을 찾고 표준에러는 error.log 파일로 재지정.
$find /tmp -name 'pulse*' 2>error.log
- 표준에러를 표준출력과 함께 재지정. 디렉터리 출력결과와 에러 모두 dirlist파일로 재지정.
$Is Deskto Documents > dirlist 2>&1 - 파이프 기능
- tee 명령어는 표준입력으로부터 데이터를 읽어 표준출력으로 출력하거나 동시에 파일에 저장할수있음.
- 파이프를 사용해 ping 명령의 출력 결과를 표준 입력으로 받아 화면과 동시에 파일에 저장
$ping google.com -c 1 | tee result.txt
- tee에 -a 옵션을 사용하고 파일명을 기재하면 파일이 새로 생서되는것이 아니라 파일 맨 끝에 추가
$ping google.com -c 1 | tee -a result.txt - 그룹 명령 기능
;는 나열한 순서대로 명령어를 실행,
||는 앞의 명령어의 실행이 성공하면 그 결과를 출력 실패하면 다음 명령어 실행
&&는 앞의 명령어의 실행이 성공한 경우에만 다음명령어 실행 - 작업 제어 기능 Job Control Command
- Job : 셸에서 실행하는 프로세스
- 작업의 세가지 상태: foreground, background, stpped
- 작업을 백그라운드로 실행할 땐 & 사용
- 작업간 전환을 위해 fg, bg 명령을 사용
- 현재 셸에서 실행한 작업의 목록은 job - 산술논리 연산기능
expr 명령어를 통해 산술, 논리 연산을 수행, 연산자와 피연산자는 공백으로 반드시 구분
기호가 특수문자에 해당하면 \, "",'' 를 사용하여야 함
| 는 앞의 피연산자가 0이거나 '' 이면 뒤의 피연산자 출력
&는 앞 또는 뒤의 피연산자가 0이거나 ''이면 0을 리턴, 그렇지않으면 앞의 피연산자 출력 - 프롬프트 제어기능
환경변수 PS1, PS2, PS3, PS4를 통해 셸 프롬프트 변경
$export PS1="dollor"
dollar - 확장된 내부 명령어
- 입출력
echo, printf, read
- 파일시스템
cd 디렉터리 변경, pwd 현재 디렉터리 표시, pushd,popd,dirs 디렉터리를 스택에 푸시,팝하거나 현재 스택의 목록은 볼때
- 변수
let 변수에 산술연산, eval 인자를 명령어로 변환, set 내부 스크립트 변수값 변경,
unset 스크립트 변수를 null로 지움, export 변수에 값을 설정
- 스크립트
source 지정한 파일을 스크립트로 실행, exit 스크립트를 종료, exec 프로세스를 실행할 때 fork하지않고 셸자체 실행
6) 셸과 메타문자
- 하나의 명령은 명령어와 명령어인자, 명령어 옵션과 옵션인자로 구성되 있고 공백으로 구분.
- 셸이 명령어에게 명령어인자, 옵션인자 등을 전달하기 전에 특별히 해석하는 특수문자 -> 메타문자
기호 | 설명 |
> | 표준출력 리다이렉션 |
>> | 표준출력 리다이렉션(데이터 끝에 추가) |
< | 표준입력 리다이렉션 |
<< | 표준입력 리다이렉션(여러줄 입력) |
* | 파일 매칭을 위한 와일드카드. 0개 이상의 글자와 매칭 |
? | 파일 매칭을 위한 와일드카드. 1개 글자와 매칭 |
[] | 파일 매칭을 위한 와일드카드. 브라켓 사이 열거한 글자들과 매칭 |
'cmd' | 명령어 치완기능을 위해 사용 |
$(cmd) | 명령어 치완기능을 위해 사용 |
| | 파이프 기능 |
: | 순차적 명령어 실행 |
|| | 앞 실행결과가 실패하면 다음 명령어 실행 |
&& | 앞 실행결과가 성공하면 다음 명령어 실행 |
() | 여러개의 명령어 그룹화, 연산자 우선순위 조절 |
& | 명령어를 백그라운드에서 실행 |
# | 설명주석 |
$ | 변수, 변수가 담고있는 값 반환 |
\ | escape 문자 해당 기호 다음 특수문자의 해석을 하지 않도록 함. |
2. 셸 프로그래밍
1) 개요
1. 셸 프로그래밍의 개념
- 셸 스크립팅
- 셸 스크립트는 셸에서 제공하는 여러 명령어를 나열한 파일. 일련의 명령어를 실행.
- 셸 스크립트를 통해 주기적 백업, 시스템 모니터링 등 반복작업 자동화
- 문법이 간단하여 작성이 쉽고 이너프리터가 명령어 해석을 바로 하기 때문에 디버깅이 쉬움.
2. 형식
- 첫번째 줄에는 해당 스크립트가 사용할 셸을 '#!'을 통해 명시
- 두번째 줄부터는 일련의 명령어를 기술
#!/bin/bash
echo "Hello World!"
3. 실행
- 별도의 프로세스로 실행하는 방법과 현재 셸에서 바로 실행하는 방법
- 별도의 프로세스로 실행하기 위해 스크립트 파일에 퍼미션 실행 권한을 주고 실행.
현재 경로를 의미하는 ./ 을 붙여야 함.
$chmod +x hello.sh
$./hello.sh
- 셸의 인자로 스크립트 파일경로를 넘겨 직접 실행. 독립된 프로세스에서 스크립트가 실행됨.
$bash hello.sh
- 현재 셸에서 바로 실행하기 위해 source 명령어나 . 명령어 이용
$source hello.sh
$. hello.sh
2) 셸 스크립트의 기본문법
1.주석 #
2. 변수 $
- 형식은 스트링만 제공
MSG="Hello World"
echo $MSG
3. 위치매개변수
- 명령줄에 지정된 인자의 위치를 나타내는 특별한 변수 $0
명령어 $1, $2 는 첫번째 두번째 인자 $@ 나 $*는 모든 위치매개변수
4. echo 문
- 스트링은 화면에 출력. -e 옵션을 사용해 특수문자 사용가능
$echo -e "Hello\nWorld"
\b 백스페이스, \f 폼피드 , \n 새로운줄 , \r 캐리지리턴, \t 탭, \\ 백슬래시
5. 다양한 조건식
숫자비교
num1 -eq num2 1과 2가 같으면 참
num1 -ge num2 1이 2보다 크거나 같으면 참
num1 -gt num2 1이 2보다 크면 참
num1 -le num2 1이 2보다 작거나 같으면 참
num1 -lt num2 1이 2보다 작으면 참
num1 -ne num2 1과 2가 다르면 참
!num1 1이 참이면 거짓이고 반대로 거짓이면 참
num1 -a num2 1과 2을 AND 한다. 모두 참이어야 함.
num1 -o num2 1과 2를 OR한다. 둘중 하나만 참이여도 참
문자열 비교
var1 = var2 1과 2가 같으면 참
var1 != var2 1과2가 다르면 참
var1 < var2 1보다 2가 크면 참
var1 > var2 1보다 2가 작으면 참
-n var1 1의 길이가 0보다 크면 참
-z var1 1의 길이가 0이면 참
파일 비교
-b file 블록 디바이스이면 참
-c file 문자 디바이스이면 참
-d file 디렉터리이면 참
-e file file존재하면 참
-x file file존재하고 실행가능하면 참
-r file file존재하고 쓰기 가능하면 참
-w file file이 존재하고 정규파일이면 참
-f file file존재하고 정규파일이면 참
-g file file에 SET-GID있으면 참
3) 셸스크립트의 조건문
1. if 문
브라켓 사이 표현식은 공백이 있어야함.
중첩 조건문도 가능.
if [ 표현식 ] then 명령문 elif [ 표현식 ] then 명령문 else 명령문 fi |
#!/bin/bash if [ "$1" = "cool" ] then echo "cool wind" elif [ "$1" = "warm" ] then echo "warm wind" else echo "Not warm wind" fi |
2. case 문
변수와 상응하는 패턴의 명령문 실행
case $변수 in 패턴1) 명령문 패턴2) 명령문 *) 명령문 esac |
#!/bin/bash NOW=$(data + "%a") case $NOW in Mon) echo "Full backup";; Tue|Wed|Thu|Fri) echo "Partial backup";; Sat|Sun) echo "No backup";; *) echo "Error";; esac |
4) 셸 스크립트의 반복문
1. for문
for $변수 in 값1, 값2 do 명령문 done |
#/bin/sh for i in 1 2 3 4 5 do echo "Looping ... number $i" done |
2. while문
while 표현식 do 명령문 done |
#!/bin/sh INPUT_STRING=hello while [ "$INPUT_STRING" != "bye" ] do echo "Please type something in (bye to quit)" read INPUT_STRING echo "You typed: $INPUT_STRING" done |
3. until문
- 표현식이 만족할 때까지 명령문 실행
until 표현식 do 명령문 done |
#!/bin/bash # 변수가 i가 6보다 크기전까지 출력 i=1 until [ $i -gt 6 ] do echo "Welcome $i times." i=$(( i+i )) done |
4. select문
select $변수 in 메뉴1 메뉴2 메뉴3 ... do 수행할 명령어 done |
#!/bin/bash select menu in who whoami quit do case $menu in who) who;; whoami) whoami;; puit) break;; *) echo "wrong menu item";; esac done |
5) 셸 스크립트의 함수
1. 함수 구문 문법
function 함수이름 { 명령문 } |
함수의 호출은 함수이름을 명시하여 호출
myfunction() { echo "Oh! it works" } myfunction |
6) 셸 스크립트의 부분 문자열 제거 Substring removal
1. 스트링과 패턴을 비교하여 매칭된 문자열 소거
${string#pattern} 맨앞부터 패턴과 가장 짧게 매치된 문자열 지움
${string##pattern} 맨앞부터 패턴과 가장 길게 매치된 문자열 지움
${string%pattern} 맨뒤부터 패턴과 가장 짧게 매치된 문자열 지움
${string%%pattern} 맨뒤부터 패턴과 가장 길게 매치된 문자열 지움
2. 문자열 앞부분 A로 시작해 1로 종료하는 패턴중 가장 짦은 매칭을 삭제하거나 긴매칭을 삭제
STR=ABC123abc123ABC # | --- | 가장 짧은 문자열# # | ---------- | 가장 긴 문자열## echo ${STR#A*1} #23abc123ABC echo ${STR##A*1} #23ABC |
3. 문자열 뒤부터 3으로 시작해서 C로 종료하는 패턴 중 가장 짧은 매칭을 삭제하거나 가장 긴 매칭을 삭제.
STR=ABC123abc123ABC # | --- | 가장 짧은 문자열% # | ---------- | 가장 긴 문자열%% echo ${STR%3*C} #ABC123abc12 echo ${STR%%3*C} #ABC12 |