안녕하세요
뚱보 프로그래머입니다.
오늘은 쉘 스크립트에 대해 알아봅니다.
shell script
1. 설정
명령 라인을 특정한 파일에 저장하고 실행하면 그 명령들이 차례대로 실행된다.
[root @edu00 /root]#cd /home/linux
[root @edu00 linux]#cat > ex1.sh
mkdir nadream
touch nadream/file_ls
clear
^d
실행을 하기 위해서는 다음의 두가지 방법이 사용된다.
[root @edu00 linux]#. ex1.sh
혹은
[root @edu00 linux]#source ex1.sh
결과를 확인하기 위해 다음 명령을 실행한다.
[root @edu00 linux]#ls nadream
2. 문법과 예제
1] 변수의 사용
변수(variables)는 기억장소로 변수에는 정수, 문자열 등이 들어간다.
[root @edu00 linux]#vi ex2.sh
### exam.sh ### 파일이름은 무엇이든 상관없다.
my="Hi ther" my라는 변수에 "Hi there"라는 값을 넣는다.
echo $my my변수 안에 들어있는 "Hi there"라는 값을 출력한다.
echo "$my" my변수 안에 들어있는 "Hi there"라는 값을 출력한다.
echo '$my' ' '안의 변수는 무시된다. $my 문자열을 출력한다.
echo \$my \$는 \뒤의 특수 문자를 출력할 때 사용한다.
echo Enter some text
read my my의 값을 키보드로부터 입력 받는다.
echo "$my"
exit
:wq
[root @edu00 linux]#. ex2.sh
실행이 끝나고 나면 logout될 것이다. exit 명령이 실행되었기 때문이다.
현재 실행 중인 bash process가 script를 해석하므로 exit 명령을 자신에게 적용시켜 logout된 것이다.
2] 스크립트 실행하는 방법
이 예제는 logout되지 않는다.
[root @edu00 linux]#vi ex2.sh
#!/bin/sh
### exam.sh ### 파일이름은 무엇이든 상관없다.
my="Hi ther" my라는 변수에 "Hi there"라는 값을 넣는다.
echo $my my변수 안에 들어있는 "Hi there"라는 값을 출력한다.
echo "$my" my변수 안에 들어있는 "Hi there"라는 값을 출력한다.
echo '$my' ''안의 변수는 무시된다. $my 문자열을 출력한다.
echo \$my \$는 \뒤의 특수 문자를 출력할 때 사용한다.
echo Enter some text
read my my의 값을 키보드로부터 입력받는다.
echo "$my"
exit
:wq
참고
#!/bin/sh
magic number는 아래에 나오는 명령들을 해석할 shell을 명시해주는 것이다. 이것을 script file의 처음에 넣어 줌으로써 실행 파일로 만들 수 있다.
'#!/bin/sh'의 의미는 아래에 나오는 명령들을 /bin/sh 프로그램이 해석할 것이라는 것이다.
[root @edu00 linux]#chmod +x ex2.sh
[root @edu00 linux]#./ex2.sh
현재 디렉토리는 PATH(환경변수)에 있지 않기 때문에 경로를 지정하여 실행한다.
새로운 bash process가 실행되어 script를 해석하므로 exit명령은 새로 실행된 bash에게 적용되어 그 process가 사라진 것이다.
3] if 와 test([])
1> 문자열 비교
string1 = string2 string1과 string2가 같으면 참
string1 != string2 string1과 string2가 같으면 거짓
-n string 문자열이 있으면 참
-z string 문자열이 null이면 참
2> 산술 비교
a -eq b a와 b가 같으면 참
-ne 같지 않다.
-gt 보다 크다.
-ge 크거나 같다.
-lt 보다 작다.
-le 작거나 같다.
! expression 부정
3> 파일 조건
-d filepath filepath가 디렉토리이면 참
-e 존재
-f 정규 파일
-g set-gid
-r 읽기 가능
-s 크기가 있으면 참
-u set-uid
-w 쓰기 가능
-x 실행 가능
4> 예제
[root @edu00 linux]#vi ex_if.sh
#!/bin/sh
### ex_if.sh ####
echo "Is it morning? Please answer yes or no."
# echo 명령은 " "안에 있는 내용을 출력
read timeofday
# timeofday라는 변수에 키보드 입력
if [ "$timeofday" = "yes" ]
# []는 test 구문이므로 []안의 내용이 true인지 false인지 구별
# timeofday 변수값이 yes이면 true를 리턴하고 아니면 false를 리턴
then // 값이 true이면 then이하의 명령을 실행
echo "Good morning"
elif [ "$timeofday" = "no" ]
# test 구문값이 false이면 다시 timeofday의 값이 no인지 test
then // no이면 then 이하의 명령을 실행
echo "Good afternoon"
else // no가 아니면 다음 명령을 실행
echo "Sorry, $timeofday not recognized. Enter yes or no."
fi // if 구문을 마칠 때 fi 입력
exit
:wq
[root @edu00 linux]#chmod 755 ex_if.sh
[root @edu00 linux]#./ex_if.sh
4] for
[root @edu00 linux] #vi for.sh
#!/bin/sh
### for.sh ###
for nadream in bar fud 43
# nadream은 in, bar, fud를 차례대로 받아서 do와 done사이의 명령을 실행
do
echo $nadream
# nadream변수를 출력한다. bar, fud, 43을 순서대로 출력
done
for nadream in $(ls)
# shell prompt 상태에서 ls 명령을 실행해서 출력되는 내용이 차례로 nadream에 들어# 가게 한다.
do
echo -n $nadream
# -n은 행을 바꾸지 않고 계속해서 출력하게 한다.
done
exit
:wq
[root @edu00 linux]#chmod 755 for.sh ; ./for.sh
5] while
while 구문은 [ ] 안의 내용이 참일 때 계속해서 do와 done 사이의 명령을 실행한다.
[root @edu00 linux]#vi while.sh
#!/bin/sh
echo "Enter password"
read trythis
while [ "$trythis" != "secret" ]
# test가 참일 동안 do와 done사이의 명령을 실행
do
echo "Sorry, try again"
read trythis
done
exit
:wq
[root @edu00 linux]#chmod 755 while.sh ; ./while.sh
[root @edu00 linux] #vi while2.sh
#!/bin/sh
nadream=1
while [ "$nadream" -le 20 ]
# nadream값이 20보다 작거나 같다.
do
echo "Here we go again"
nadream=$(($nadream+1))
# nadream에 1을 더한 값을 다시 nadream에 넣는다.
done
exit
:wq
[root @edu00 linux]#chmod 755 while2.sh ; ./while2.sh
6] bash shell에서 login시 실행되는 script
[root @edu00 linux]#cat ~/.bashrc
## .bashrc
## User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
## Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
[root @edu00 linux]#cat /etc/profile
## /etc/profile
## System wide environment and startup programs
# Functions and aliases go in /etc/bashrc
if ! echo $PATH | /bin/grep -q "/usr/X11R6/bin" ; then
PATH="$PATH:/usr/X11R6/bin"
fi
ulimit -S -c 1000000 > /dev/null 2>&1
if [ `id -gn` = `id -un` -a `id -u` -gt 14 ]; then
umask 002
else
umask 022
fi
USER=`id -un`
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
HOSTNAME=`/bin/hostname`
HISTSIZE=1000
if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then
INPUTRC=/etc/inputrc
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC
for i in /etc/profile.d/*.sh ; do
if [ -x $i ]; then
. $i
fi
done
unset i
7] until
while과 반대로 작동한다.
거짓일 경우 do와 done사이의 명령을 수행한다.
[root @edu00 linux]#vi until.sh
### unitl.sh ###
#!/bin/sh
until who | grep "$1" > /dev/null
# who | grep "$1" > /dev/null 명령이 실행될 때까지 do, done 사이의 명령을 실행한다.
# 즉 조건이 참이면 실행을 멈춘다.
do
sleep 30 # 30초 동안 아무것도 하지 않는다.
done
echo "***** $1 has just logged in ****"
# $1은 script를 실행할 때 인수로 쓰이는 것을 말한다.
exit
[root @edu00 linux]#chmod 755 unil.sh ; ./until.sh nadream angel
$0은 ./until.sh $1은 nadream, $2는 angel
8] case
[root @edu00 linux]#vi case.sh
#!/bin/sh
echo "Is it morning? Please answer yes or no"
read timeofday
case "$timeofday" in
"yes" | "y" | "Yes" | "YES" )
# timeofday가 4개 중의 하나라면 아래 명령을 실행한다.
echo "good morning"
echo "Up bright and early this morning";;
[Nn]* )
# 메타 문자가 사용 가능하다.
# 앞에 N이나 n이 오고 뒤에는 아무런 문자가 와도 된다.
echo "good afternoon";;
* )
echo "Sorry, answer not recognized"
# 위에 설정된 문자 외의 값을 갖는 경우에는 아래 명령을 실행한다.
echo "Please answer yes or no"
exit 1
;;
esac
# case 문을 마칠 때 반대인 esac로 한다.
exit
[root @edu00 linux]#chmod 755 case.sh ; ./case.sh
9] and
statement1 && statement2 && statement3 ... 왼쪽부터 시작하여 그 결과값이 참이면 그 다음 명령이 수행된다. 하나의 구문이 거짓이 될 때까지 수행을 계속하며, 구문이 거짓을 반환한다면 더 이상 구문은 수행되지 않는다.
[root @edu00 linux]#vi and.sh
#!/bin/sh
touch file_one
rm -f file_two
# 4개의 조건이 모두 만족하면 if in, 그렇지 않으면 in else
# file_one이 있다면 echo 명령을 실행하고 file_two가 있다면 그 다음 echo 명령을
# 실행하게 된다. 만약 이 조건 중 하나라도 거짓이 나오면 거짓이 된다.
if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo "there"
then
echo "if in"
else
echo "in else"
fi
exit 0
:wq
10] or
statement1 || statement2 || ...
왼쪽부터 시작하여 그 결과값이 거짓이면 오른편의 명령이 수행된다.
하나의 구문이 참이 될 때까지 수행을 계속한다.
만일 어떤 구문이 참을 반환하면 더 이상 수행하지 않는다.
[root @edu00 linux] #vi or.sh
#!/bin/sh
rm -f file_one
if [ -f file_one ] || echo "hello" || echo "there"
# file_one이 있다면 다음의 echo 명령을 수행하지 않는다.
# 없다면 echo "hello"를 수행하고 그 뒤의 echo "there"는 수행하지 않는다.
# 3개 중 어느 하나가 참이면 참이 된다.
then
echo "in if"
else
echo "in else"
fi
exit 0