티스토리 뷰
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
#
#
# 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`
$ 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 `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 $?
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!
#
#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 $@"
#!/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
$ cat cap_names
ASHISHEK
ASHISH
ZEBRA
BABU
tr 명령어는 소문자를 대문자로 바꿔준다.
sname 파일로부터 일력 받아 변환 후 cap_names 에 출력한다.
$ sort > new_sorted_names < sname
$ cat new_sorted_names
$ 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
반응형
댓글