[네이버클라우드] AIaaS 개발자 과정/Linux

[네이버클라우드캠프] 2023.5.3 Linux(1) - Shell Script

_꼬마돌 2023. 5. 3. 09:37
반응형

Shell Script (Shell Programming)

Shell의 종류

  Bourne Shell (sh)   79년. Bell연구소 Steven Bourne이 개발
  C Shell (csh)   버클리 대학교에서 Bill Joy가 개발
  C언어와 비슷한 문법을 사용
  TC Shell (tcsh)   C Shell의 확장판
  Korn Shell (bash)   AT&T사의 David Korn이 개발
  Bourne Shell의 확장판
  Bourne Again Shell (bash)   Bourne Shell을 기반으로 C Shell과 Korn Shell의 장점까지 포함한 강력한 Shell
  자유소프트웨어 재단의 Brian Fox가 개발. Linux의 기본 Shell.
  Debian Shell (dash)   데비안 리눅스 배포판에서 사용하는 Shell.
  많이 사용하지는 않는다.
  Zsh   Paul Falstad가 개발
  프로그래머를 위한 고급 Shell.

 

현재 사용 중인 Shell 확인하기

현재 사용중인 Shell을 확인할 수 있는 두 가지 방법이 있다.
root@kwc:~# echo $SHELL          => 가장 간단한 방법이다. 대문자로 입력해야한다.
/bin/bash                        => bash 사용중

root@kwc:~# ps -p $$             => 'process status' 명령어에 프로세스ID를 지정하는 옵션인 -p를 사용. $$는 현재 shell의 프로세스 ID를 나타내는 변수다.
    PID TTY          TIME CMD
   1241 pts/1    00:00:00 bash   => bash 사용중

 

사용 가능한 Shell 목록 출력하기

root@kwc:~# nl /etc/shells               => /etc/shells: 사용 가능한 Shell의 경로를 포함하는 파일 
     1  # /etc/shells: valid login shells
     2  /bin/sh
     3  /bin/bash
     4  /usr/bin/bash
     5  /bin/rbash
     6  /usr/bin/rbash
     7  /usr/bin/sh
     8  /bin/dash
     9  /usr/bin/dash
    10  /usr/bin/tmux
    11  /usr/bin/screen
    12  /usr/bin/zsh

 

다른 Shell로 바꾸기

root@kwc:~# chsh -s /bin/zsh   => 'change shell' 명령어에 변경할 shell의 경로를 지정하는 -s 옵션사용.
                                   사용가능한 shell 목록에 있는 shell을 입력해야한다.
root@kwc:~# echo $SHELL            
/bin/bash                      => 변경된 Shell을 적용하기 위해서는 로그아웃 후 다시 로그인해야한다.

--새로 로그인--
login as: j
j@127.0.0.1's password:
j@kwc:~$ sudo -i
[sudo] password for j:
kwc#                           => shell prompt가 엄청 단순해졌다. 

kwc# echo $SHELL               
/bin/zsh                       => zsh로 바뀌어있다.

kwc# chsh -s /bin/bash         => 다시 bash로 변경하고 새로 로그인!

 

Shell의 명령어 해석 순서

1. alias
2. keyword
3. function
4. builtin
5. 외부 명령어

compgen -a | column    => 현재 환경에서 사용 가능한 모든 별칭(alias) 표시
compgen -k | column    => 현재 환경에서 사용 가능한 모든 키워드(keyword) 표시
compgen -c | column    => 현재 환경에서 사용 가능한 모든 명령어(command) 표시
compgen -b | column    => 현재 환경에서 사용 가능한 모든 shell 내장 명령어(builtin) 표시

 

Shell Script 실습

root@kwc:~/d8# vi a.sh                 => 'a' 쉘 스크립트 파일 생성

스크립트 파일 내 입력
  1 #!/bin/bash
  2
  3 echo
  4 echo " 오늘은 수요일 "
  5 d=`date`                           => back tick (`)
  6 d1=$(date)
  7 now=`date +%Y년%m월%d일::%H시%M분` => back tick (`)
  8 echo -e " 오늘은 $d \n $d1 "
  9 echo " 지금 시간은 : $now "
  10 echo

root@kwc:~/d8# ./a.sh              => 현재 디렉토리에서 a.sh 실행
-bash: ./a.sh: Permission denied   => 실행권한이 없을 때 발생하는 오류. 권한설정을 해줘야 한다.

root@kwc:~/d8# chmod +x a.sh       => chmod 명령어로 a.sh 파일에 실행 권한 부여. (chmod 755 a.sh 를 입력해도 된다.)

root@kwc:~/d8# ./a.sh              => 권한을 부여하고 실행하면 잘 된다.

 오늘은 수요일
 오늘은 Fri May  5 08:30:38 AM UTC 2023
 Fri May  5 08:30:38 AM UTC 2023
 지금 시간은 : 2023년05월05일::08시30분

root@kwc:~/d8# PATH=$PATH:.        => 경로에 현재 위치를 추가하면
root@kwc:~/d8# a.sh                => './' 를 입력하지 않아도 실행된다. 

 오늘은 수요일
 오늘은 Fri May  5 08:33:54 AM UTC 2023
 Fri May  5 08:33:54 AM UTC 2023
 지금 시간은 : 2023년05월05일::08시33분

 

 

리눅스 종료 상태 코드

코      드 의      미
0   성공
1   알 수 없는 오류, 일반적인 error
3   명령어 잘못 사용, Syntax error
126   실행할 수 없음
127   명령어를 찾을 수 없음
128   잘못된 종료 매개 변수
128+x   치명적인 오류로 리눅스 신호x에 의한 종료
130   ^C (Ctrl+C)로 명령어 종료
255   범위를 벗어난 종료 상태
  Shell의 종료 상태 참 : 0, 거짓 : 0이 아닌 모든 값
  echo $? : 직전에 실행된 명령어의 종료 상태(exit status)를 출력

  함수 종료 : return
  스크립트 종료 : exit

 

Bash Shell 특수 값

문      자 의      미
$?   바로 이전 명령의 상태 종료 값
$$   현재 Shell PID
$!   가장 최근에 실행중인 background PID
$_   이전 명령어의 마지막 인수, 없으면 명령 리턴
$-   set 명령어의 의해 enable된 옵션. flags
$0   실행중인 프로그램 이름. scriptname
$#   인수의 갯수
$*   $1, $2, $3 ... 모든 매개변수를 하나로 참조
$@   $1, $2, $3 ... 모든 매개변수를 개별 참조

 

Redirection

문      자 의      미
 <   입력
>   출력
>>   덧붙임
<<   Here Document (여러 줄로 이루어진 문자열을 명령어에 전달하는 방법)
  일괄적으로 처리해야 하는 일련의 명령어나 스크립트를 입력할 수 있다.
  예시) cat > a1 << EOF    a1 파일의 내용을 입력할 때 EOF를 입력하면 입력 종료 후 저장
            cat << EOF > a1 과 같다.
2>파일   파일로 에러를 redirect
&>file   표준 출력과 표준 에러를 동시에 file로 redirect
>&file   표준 출력과 표준 에러를 동시에 file로 redirect
   
cal 1>b   표준 출력을 파일로 출력
cal0<b   파일로부터 입력받아 cat 실행
   
date >> b   b파일에 date결과 덧붙임
2>/dev/null      =>     error 메시지 보이지 않게 하기

 

Shell 스크립트를 이용하여 Linux  패키지 설치 자동화하기 (작업 정보 자동 기록까지!)

root@kwc:~# vi init.sh     => 'init' 쉘 스크립트 파일 생성

---파일 편집기 입력 내용---
  1 timedatectl set-timezone 'Asia/Seoul'          => 서울로 시간 설정
  2 now=`date +%Y년%m월%d일::%H시%M분`             => 현재 날짜와 시간을 Y년m월d일::H시M분 형식으로 포맷하여 'now'변수에 할당. back tick (`) 사용.
  3
  4 echo $now >> ~/out.txt                         => 위에서 설정한 now를 out.txt 파일에 추가
  5 apt list  --installed  | wc -l >>  ~/out.txt   => 현재 시스템에 설치된 패키지의 개수를 세어 out.txt 파일에 추가
  6 echo $now >> ~/out.txt                         => 현재 날짜와 시간을 다시 out.txt 파일에 추가
  7
  8 apt-get  -y  install  gcc g++ default-jdk mysql-server sqlite3 tomcat9 apache2  => 패키지 설치
  9
 10 apt-get  -y install  php php-curl php-gd php-intl php-mbstring php-soap php-xml \
 11                       php-xmlrpc php-zip php-mysql                              => 패키지 설치
 12
 13 apt list  --installed  | wc -l >>  ~/out.txt   => 모든 패키지 설치 후 시스템에 설치된 패키지의 개수를 다시 세어 out.txt파일에 추가 
 14 echo $now >> ~/out.txt                         => 현재 날짜와 시간을 다시 out.txt 파일에 추가
out.txt 파일에 5번에 걸쳐 정보를 저장하여 파일이 실행된 후 해당 작업에 대한 정보를 확인할 수 있도록 했다.
1. 파일이 처음 실행될 때의 시간
2. 이미 설치되어 있는 패키지의 수
3. 패키지 설치가 시작될 때의 시간
4. 설치 후 최종 패키지 개수
5. 모든 작업이 끝난 시간

root@kwc:~# chmod +x init.sh      => 파일 내용을 저장하고 실행하기 전에 권한을 부여해야 한다.
root@kwc:~# init.sh               => 파일 실행

root@kwc:~# nl out.txt            => 작업이 끝난 후, out.txt 파일을 실행해보면 작업에 걸린 시간과 설치된 패키지의 수를 확인할 수 있다.
     1  2023년05월03일::20시30분  => 파일 실행 시간
     2  657                       => 패키지 설치 전 패키지 수
     3  2023년05월03일::20시30분  => 패키지 설치 시작 시간
     4  827                       => 패키지 설치 후 패키지 수
     5  2023년05월03일::20시32분  => 작업 끝난 시간

 

Shell Script 예제

root@kwc:~# vi b.sh                   => 'b' 쉘 스크립트 파일 생성

--편집기 입력 내용---
  1 #!/bin/bash
  2 echo " 스크립트 이름 : $0 "
  3 echo " \$1 : $1 "
  4 echo " \$2 : $3 "
  5 echo " \$3 : $3 "
  6 echo " \$4 : $4 "
  7 echo "  argument 개수 : $# "
  8 echo "  모든 값 출력  : $* "

root@kwc:~# chmod +x b.sh               => 편집기 내용 저장 후 권한 부여
root@kwc:~# b.sh                        => 파일 실행
 스크립트 이름 : ./b.sh
 $1 :
 $2 :
 $3 :
 $4 :
  argument 개수 : 0
  모든 값 출력  :                         => 그냥 실행하면 스크립트만 출력된다.
  
  root@kwc:~# b.sh 영희 철수 짱구 맹구    => 실행할 때 입력할 값을 함께 넣어주면 순서대로 스크립트에 들어간다.
 스크립트 이름 : ./b.sh
 $1 : 영희
 $2 : 짱구
 $3 : 짱구
 $4 : 맹구
  argument 개수 : 4
  모든 값 출력  : 영희 철수 짱구 맹구
  
  root@kwc:~# b.sh 영희 철수 짱구 맹구 진구 훈이  => 만들어둔 4자리보다 많은 6개의 값을 넣어보았다.
 스크립트 이름 : ./b.sh
 $1 : 영희
 $2 : 짱구
 $3 : 짱구
 $4 : 맹구                                        => 네번째인 맹구까지만 들어간다.
  argument 개수 : 6                              
  모든 값 출력  : 영희 철수 짱구 맹구 진구 훈이   => argument 개수는 6개, 모든 값 출력은 6개 모두 출력된다.

 

C 언어 컴파일 이용하여 인수 개수 세기

root@kwc:~# vi a1.c

--편집기 입력 내용--
  1 #include <stdio.h>
  2 int main(int a, char* b[])
  3 {
  4     int i=0;
  5     printf(" 인수의 개수 = %d \n", a);
  6
  7     for (i=0; i<a; i++)
  8         printf(" \b[%d] ==> %s \n", i, b[i]);
  9     return 0;
 10 }


root@kwc:~# gcc -o a1 a1.c    => 컴파일
root@kwc:~# a1           
 인수의 개수 = 1              => 스크립트의 이름도 인수의 개수에 포함된다.
[0] ==> a1

root@kwc:~# a1 영희 철수 짱구 맹구 진구 훈이  => 아까와 같이 6개의 값을 입력했다.
 인수의 개수 = 7                              => 입력한 6개의 값에 1이 더 많다.
[0] ==> a1                                    => 0번째 인수는 스크립트의 이름.
[1] ==> 영희
[2] ==> 철수
[3] ==> 짱구
[4] ==> 맹구
[5] ==> 진구
[6] ==> 훈이


반응형