Linux

셸 Shell

laughcryrepeat 2020. 8. 13. 00:38

1. 셸의 이해

 

1) 셸의 개념

  1. 일반적인 셸의 정의
    - 사용자가 커널의 서비스 기능을 사용할 수 있도록 하기 위한 통로 또는 사용자 인터페이스.
    - 명령줄 인터페이스 방식 CLI 과 그래픽 유저 인터페이스 방식 GUI로 구분
    - 주로 CLI 방식으로 사용
  2. 리눅스 셸의 역사
    - 71년 유닉스에 도입된 최초의 셸, 톰프슨 셸
    - 77년 기본 유닉스 셸, 본셸. AT&T의 벨연구소 스티븐 본이 개발.
    - 70년대 후반 빌조이가 C언어를 기반으로 개발한 C셸
    - 83년 C셸의 기능을 포함한 콘셸을 개발
    - 자유 소프트웨어 진영에서 bash 셸 등장. 리눅스의 기본 셸.
  3. 특징
    - 사용자로부터 명령어를 입력받고 해석하여 처리하는 대화형 인터페이스
    - 셸을 통해서 쉽게 파일관리, 프로세스 관리, 배치 프로세싱, 성능 모니터링, 환경 설정 등 커널의 기능을 사용할 수 있음.
    - 일반 응용프로그램과 같이 커널이 제공하는 시스템 콜을 통해 구현.
    - 사용자가 커널에게 쉽게 명령을 내릴수있게 만든 기본 탑재 응용 프로그램.

2) 셸의 유형

본셸계열 - sh (bourne shell), ksh (korn shell), bash (bourne again shell)

C셸계열 - csh (C shell), tcsh (TCshell)

 

3) 셸의 설정 및 확인

  1. 현재 셸의 확인
    환경변수 SHELL을 통해 로그인한 사용자 셸 확인
    $echo $SHELL
    /bin/bash
  2. 시스템이 지원하는 셸 목록 확인 -1
    chsh 명령어의 -I 옵션을 사용하여 시스템이 지원하는 셸목록을 확인할 수 있음
    $ chsh -I
    /bin/sh
    /bin/bash
    /sbin/nologin
    ...
  3. 시스템이 지원하는 셸 목록 확인 -2
    /stc/shells 파일에 시스템이 지원하는 셸 목록이 기록되어 있어 이 파일을 확인.
    $cat /etc/shells
    /bin/sh
    /bin/bash
    /sbin/nologin
    ...
  4. 셸의 변경
    chsh 명령어의 -s 옵션을 사용하여 셸을 변경
    $chsh -s /bin/csh
    Changing shell for trancis
    Password:
    Shell changed
  5. 특정 사용자의 셸 확인
    $cat /etc/passwd | grep francis
    francis:x500:500:francis:/home/francis:/bin/csh 
  6. 환경변수를 통한 설정 확인
    set 명령어로 확인
    $set
    DISPLAY=:0.0
    HISFILE=/home/francis/.bash_history
    HISFILESIZE=1000
    HOME=/home/francis
    ...
  7. 환경변수를 통한 설정 예제
    :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) 셸의 시작과 종료

  1. 로그인 셸과 비로그인 셸
    - 로그인 셸. userid와 passwd 입력하여 셸에 진입하는 방식
    - 비로그인 셸. 로그인 없이 셸을 실행하는 것. bash명령어를 사용해 셸을 사용하거나, x윈도우 터미널 실행.
  2. 인터랙티브 셸과 비 인터렉티브 셸
    - 인터랙티브 셸. 대화형으로 셀을 통해 명령을 입력하고 결과를 받을수 있는 상태의 셸.
    - 비 인터랙티브 셸. 셸 스크립트에서 셸을 실행하는 경우. #!/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/bashrc
    사용자 설정파일
    ~/.bash_profile, ~/.bash_login, ~/.profile, ~/.bashrc, ~/.bash_logout

5) 셸의 기능

  1. 자동완성 기능(bash-completion)
    현재 경로에 입력하려는 문자와 매칭되는 파일명이나 명령 후보를 자동으로 보여줌. TAB 입력하여 후보 확인.
  2. 히스토리 기능
    - 사용자가 입력한 명령어가 보관이 됨. 저장 명령어를 열람하고 실행 가능.
    $history
    - 특정 명령어를 실행하기 위해 열람한 번호를 !와 붙여 사용
    !2
    - 히스토리 지우기
    $history -c
    - 직전 명령어 입력
    $!!
    - 최근 3개 히스토리
    $history 3
  3. alias 기능
    - alias 설정
    $alias show-me-passwd='cat /etc/passwd'
    - alias 해제
    $unalias show-me-passwd
  4. 셸 키보드 단축키
    - 여러 텍스트 제어 단축키 제공
  5. 명령어 치환 기능 Command substitution
    - 명령어의 실행 결과를 명령어의 인자로 넘기는 기능
    $(command) 또는 'command'
    - touch 명령어를 통해 현재시각을 파일명으로 갖는 파일 생성
    $touch "$(date)"
  6. 표준 입출력 기능
    - 사용자의 입력을 프로그램에 전달하고 결과를 보여줌.
    표준입력 stadin 0 데이터 입력 기본장치
    표준출력 stdout 1 출력 기본장치
    표준에러 stderr 2 오류발생시 출력 기본장치
  7. 리다이렉션 기능
    -표준 출력과 > , >>
    -표준 입력과 < , <<
    - 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
  8. 파이프 기능
    - tee 명령어는 표준입력으로부터 데이터를 읽어 표준출력으로 출력하거나 동시에 파일에 저장할수있음.
    - 파이프를 사용해 ping 명령의 출력 결과를 표준 입력으로 받아 화면과 동시에 파일에 저장
    $ping google.com -c 1 | tee result.txt
    - tee에 -a 옵션을 사용하고 파일명을 기재하면 파일이 새로 생서되는것이 아니라 파일 맨 끝에 추가
    $ping google.com -c 1 | tee -a result.txt
  9. 그룹 명령 기능
    ;는 나열한 순서대로 명령어를 실행,
    ||는 앞의 명령어의 실행이 성공하면 그 결과를 출력 실패하면 다음 명령어 실행
    &&는 앞의 명령어의 실행이 성공한 경우에만 다음명령어 실행
  10. 작업 제어 기능 Job Control Command
    - Job : 셸에서 실행하는 프로세스
    - 작업의 세가지 상태: foreground, background, stpped
    - 작업을 백그라운드로 실행할 땐 & 사용
    - 작업간 전환을 위해 fg, bg 명령을 사용
    - 현재 셸에서 실행한 작업의 목록은 job
  11. 산술논리 연산기능
    expr 명령어를 통해 산술, 논리 연산을 수행, 연산자와 피연산자는 공백으로 반드시 구분
    기호가 특수문자에 해당하면 \, "",'' 를 사용하여야 함
    | 는 앞의 피연산자가 0이거나 '' 이면 뒤의 피연산자 출력
    &는 앞 또는 뒤의 피연산자가 0이거나 ''이면 0을 리턴, 그렇지않으면 앞의 피연산자 출력 
  12. 프롬프트 제어기능
    환경변수 PS1, PS2, PS3, PS4를 통해 셸 프롬프트 변경
    $export PS1="dollor"
    dollar
  13. 확장된 내부 명령어
    - 입출력
    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