티스토리 뷰

시스템 서버

[linux] Shell Script 공부 2일차 - Chapter 2

달리는개발자 2011. 10. 22. 11:01

Chapter 2 : Getting Started with Shell Programming

쉘 프로그래밍을 소개하고 스크립트를 어떻게 작성하는지 그리고 실행하는지를 소개합니다.

쉘 스크립트를 어떻게 작성하는가?
쉘 스크립트 작성법은 다음과 같다.
1. vi 또는 mcedit 같은 에디터를 사용한다.
2. 쉘 스크립트 작성 후에 스크립트 파일에 실행 권한을 설정한다.
    chomod permission your-script-name
   
$ chmod +x your-script-name

   
$ chmod 755 your-script-name

3. 스크립트를 실행한다.
   bash your-script-name
   sh your-script-name
   ./your-script-name
  
$ bash bar

  
$ sh bar

  
$ ./bar

   쉘의 새 복사본없이 실행하려면 다음과 같이 실행한다.
   .command-name
  
$ .foo


화면에 "아는 것이 힘이다" 라고 출력하는 첫번째 쉘 스크립트를 작성해 보자.
$ vi first
#
# My first shell script
#

clear
echo "Knowledge is Power"

위의 스크립트를 저장 후에 다음과 같이 실행해보자.
$ ./first


이것은 실행권한이 없어서 동작하지 않을 것이다.
다음과 같은 명령어로 권한을 부여합니다.

$ chmod 755 first

$ ./first


화면이 지워진 다음 Knowledge is Power 가 출력될 것이다.

How Shell locates the files
쉘이랑 스크립트 파일은 같은 위치에 있어야 된다.
그렇지 않은 경우 다음과 같이 완전한 경로를 적어줘야한다.
$ /bin/sh /home/abhishek/first
PATH에 설정을 해줘도 된다...
그리고 쉽게 인지할 수 있도록 쉘 스크립트의 확장자를 .sh로 준다.

$ vi ginfo
#
#
# Script to print user information who currently login , current date & time
#
clear
echo "Hello $USER"
echo "Today is \c ";date
echo "Number of user login : \c" ; who | wc -l
echo "Calendar"
cal
exit 0


배치 작업에서 exit code는 표준 유닉스 종료 상태이다.
제대로된 유닉스 어플리케이션은 운영체제에 그것이 성공했는지 아닌지를 알려준다.
그것은 0~255인 exit 상태를 의미한다.
0은 성공이고 다른 것들은 실패이다.
exit 상태는 두가지 중요한 특징을 제공한다. 첫째는 에러를 발견하고 다룰 수 있으며
둘째는 참/거짓 테스트를 수행할 수 있다.

쉘의 변수들
1. 시스템 변수들
    리눅스에 의해 생성되고 유지하는 것들. 이 변수들은 대문자(CAPITAL LETTERS)로 정의된다.
2. 사용자 정의 변수(User Defined Variables - UDV)
    사용자에 의해 생성되고 유지하는 것들. 이 변수들은 소문자(lower letter)로 정의된다.
$ set 명령어를 통해서 시스템 변수들을 볼 수 있다.
다음은 중요한 시스템 변수들이다.
 System Variable Meaning 
 BASH=/bin/bash  쉘 이름
 BASH_VERSION=1.14.7(1)  쉘 버전명
 COLUMNS=80  화면의 column 수(숫자)
 HOME=/home/abhishek  홈 디렉토리
 LINES=25  화면의 라인 수(숫자)
 LOGNAME=students  students Our logging name
 OSTYPE=Linux  OS type
 PATH=/usr/bin:/sbin:/bin:/usr/sbin  설정된 경로
 PS1=[\u@\h\w]\$  Our prompt settings
 PWD=/home/students/Common  현재 작업 디렉토리
 SHELL=/bin/bash  쉘명
 USERNAME=abhishek 현재 접속된 사용자명 

다음과 같이 변수들을 출력한다.

$ echo $USERNAME

$ echo $HOME

시스템 변수를 수정하게 되면 문제를 일으킬 수 있기 때문에 수정하지 마라.

사용자 정의 변수(User Defined Variables - UDV)는 어떻게 정의하나?
변수를 정의하기 위한 구문은 다음과 같다.
변수명=값
값은 주어진 변수명에 할당되고 값은 반드시 = 오른쪽에 위치한다.
$ no=10 # this is OK

$ 10=no # Error


변수의 명명규칙(사용자 정의 변수, 시스템변수)
1. 변수는 알파벳 문자또는 underscore character(_)로 시작해야되고 한개 이상의 알파벳 문자가 포함되야 한다.
2. 변수 할당 시에 빈칸이 들어가서는 안된다.
   
$ no=10 (O)

    
$ no= 10 (X)

   
$ no =10 (X)

    
$ no = 10 (X)

3. 리눅스의 파일명과 같이 대소문자를 구분한다.
   
$ no=10

    
$ No=10

4. 다음과 같이 NULL 변수를 지정할 수 있다.
   
$ vech=

   
$ vech=""

5. 변수명에 ? 과 * 등을 사용할 수 없다.

사용자 정의 변수값에 어떻게 접근하고 출력하는가?
$변수명

변수 정의
$ vech=Bus

$ n=10


변수 출력
$ echo $vech

$ echo $n


다음과 같이 입력하면 단지 vech, n 이란 문자만 출력될 것이다. 꼭 변수에는 $을 붙이도록 하자.
$ echo vech

$ echo n

Echo 명령어
문자나 값을 출력하기 위해 echo 명령어를 사용한다.
echo [options] [string, variables...]
Options
-n new line을 출력하지 않는다.
-e 문자열 안에 있는 backslash escaped character들을 출력한다.
\a alert (bell)
\b backspace
\c suppress trailing new line
\n new line
\r carriage return
\t horizontal tab
\\ backslash
For e.g. $ echo -e "An apple a day keeps away \a\t\tdoctor\n"

리눅스 콘솔(화면)
어떻게 리눅스 콘솔에 다채로운 메시지를 작성할 수 있을까?
리눅스 콘솔은 ANSI escape sequence code 를 지원하는 DEC VT100 시리얼 터미널에 기반을 두고 있다.

$ echo "Hello World"
$ echo -e "\033[34m Hello Colorful World!"

위에 문장은 ANSI escape sequence (\033[34m)을 사용하였다. 위에 문장은 다음과 같이 처리된다.
1) First \033 is escape character, which causes to take some action
2) here it set screen foreground color to Blue using [34m escape code.
3) Then it prints our normal message Hello Colorful World!, in blue color.

ANSI escape sequence는 \033 (8진수) 로 시작한다.

echo -e "\033[escape-code your-message"

\033이 나오면 escape mode로 변경되고 "[" 문자를 읽고 Command Sequence Introduction (CSI) mode 로 움직인다.
CSI mode 콘솔에서 세미콜론(;)으로 구분된 ASCII-coded 10진수를 읽는다.
이 숫자들은 console action letter나 character 를 찾지 못할 때 읽는다.

 \033  Escape character
 [ Start of CSI 
 34  34 is parameter
 M  m is letter (specifies action)

18P ~ 19P 참고

쉘 연산
구문
expr op1 meth-operator op2
예제
$ expr 1 + 3
$ expr 2 - 1
$ expr 10 / 2
$ expr 20 % 3
$ expr 10 \* 3
$ expr `expr 6 + 3`

맨 마지막 문장은 `(back quote) 임.
single quote나 double quote 인 경우는 동작을 안함.

Parameter substitution(매개변수 치환)
다음과 같은 형태이다.
$ ($ echo `expr 6 + 3`)

명령어에서 backquotes로 감싸있고, 실행되서 출력될 것이다.
대부분 다른 명령어와의 결합에 사용된다.
$ pwd
$ cp /mnt/cdrom/lsoft/samba*.rmp `pwd`

위와 동일한 명령어
$ cp /mnt/cdrom/lsoft/samba*.rmp .


Exit 상태
리눅스에서 기본적으로 특정 명령어나 쉘 스크립트가 실행됐을 때 그것이 성공했는지 아닌지를 보여준다.
1. 0이 반환되면 명령은 성공
2. 0이 아닌 값이면 명령이 성공하지 못했거나 일부 에러가 있다.

어떻게 명령어나 쉘 스크립트의 exit 상태를 찾을 수 있나?
다음과 같다.
$ rm unknow1file
rm: cannot remove 'unknow1file' : No such file or directory
$ echo $?
$ ls
$ echo $?


The read Statement
$ vi sayH
#
#Script to read your name from key-board
#
echo "Your first name please:"
read fname
echo "Hello $fname, Lets be friend!"

$ chmod 755 sayH
$ ./sayH
your first name please : shuiky
Hello shuiky, Lets be friend!


한 줄에 여러 명령어를 실행
구문
command1; command2
예제
$ date; who


왜 command line 인자가 필요한가?
1. 명령에 사용할 옵션을 말해준다.
2. 처리(읽거나 쓸)할 파일들을 알려준다.

$ vi demo
#!/bin/sh
#
# Script that demos, command line args
#
echo "Total number of command line argument are $#"
echo "$0 is script name"
echo "$1 is first argument"
echo "$2 is second argument"
echo "All of them are :- $* or $@"


표준 입출력를 리다이렉션한다.
입출력을 파일을 통해할 때 사용한다.
>, >>, < 와 같이 세 종류의 기호가 있다
(1) >
쉘 스크립트나 명령의 출력을 파일에 저장한다.
기존 파일이 있는 경우 덮어쓴다.
(2) >>
쉘 스크립트나 명령의 출력을 파일에 저장한다.
기존 파일이 있는 경우 파일의 마지막 부분에 추가한다.
(3) <
리눅스 명령을 키보드 대신 파일을 이용한다.

다음 명령어는 어떻게 실행될까?
$ sort < sname > sorted_names
$ cat sorted_names
ashish
babu
abhishek
zebra

위 예제는 sname 파일을 입력 받아서 정렬 후에 sorted_names 파일에 출력한다.

또 다른 예제를 보자.
$ tr "[a-z]" "[A-Z]" < sname > cap_names
$ cat cap_names
ASHISHEK
ASHISH
ZEBRA
BABU


tr 명령어는 소문자를 대문자로 바꿔준다.
sname 파일로부터 일력 받아 변환 후 cap_names 에 출력한다.

$ sort > new_sorted_names < sname
$ cat new_sorted_names


위의 예제는 sname 파일로부터 입력을 받아서 정렬 후에 new_sorted_names로 출력한다.

Pipes
파이프(|)는 한 프로그램에서 또 다른 프로그램을 임시 파일 없이 연결하는 방법이다.
파이프는 다음과 같이 정의할 수 있다.
파이프는 한 명령어의 출력이 저장된 임시의 저장공간이고 두번째 명령어를 위한 입력을 보낸다.
같은 command line으로 부터 2개 이상을 실행시킨다.
구문
command1 | command2
예제
$ ls | more

$ who | sort

$ who | sort > user_list

$ who | wc -l     //현재 로그인된 사람의 수

$ ls -l | wc -l     //현재 디렉토리의 파일 수

$ who | grep raju   


Filter
100줄 정도의 데이터가 있는 hotel.txt 파일이 있다고 가정하고, 20번째줄부터 30줄을 출력하고 hlist라는 파일에 저장하길 원한다면 다음과 같은 명령어를 실행한다.
$ tail -n +20 < hotel.txt | head -n30 > hlist

Process와 관련된 명령어
프로세스란 사용자가 명령한 특별한 작업을 수행하는 프로그램이다.
리눅스에서 프로세스를 시작할 때 0-65535 사이의 PID(process-id)가 주어진다.
리눅스는 멀티유저와 멀티태스킹 두개 이상의 작업이 동시에 실행될 수 있다.
$ ls / -R | wc -l

$ ls / -R | wc -l &

실행 중인 명령 인스턴스를 프로세스라고 부르고 쉘에 의해서 출력된 숫자를 PID로 불린다.

현재 실행 중인 프로세스 보기
$ ps

PID 1012 실행 중단(멈추기)
$ kill 1012

이름으로 실행 중단
$ killall httpd

모든 실행 중인 프로세스 정보 보기
$ ps -ag

당신의 shell을 제외한 모든 프로세스 실행 중단
$ kill 0

백그라운드 실행(&)
$ ls / -R | wc -l &

프로세스에 속한 사용자보기
$ ps aux

특정 프로세스가 실행 중인지 아닌지를 확인
$ ps ax | grep httpd

현재 실행 중인 프로세스들과 메모리와 CPU 사용량 같은 정보들을 실시간으로 보기
$ top

프로세스 트리 보기
$ pstree



반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함