요약
01 셸 스크립트
02 셸 변수 사용하기
03 사용자로부터 입력 받기
04 연산자
05 제어문
06 함수
07 디버깅
요약
연습문제
#!/bin/bash
# My First Script Program
echo I love Linux !
pwd
# 쉘을 실행하면서 인자로 스크립트 이름 지정
$ bash test_script
I love Linux!
/home/user1/Linux/ch11
$
# 파일을 직접 실행 : 스크립트 파일의 실행권한이 있어야만 실행가능
#chmod 라는 커맨드로 실행 권한을 주면 그 다음부터는 그 스트립트 파일을 실행시킬 수 있다
$ chmod +x test_script # +x 는 user, group, others 에 대해 실행권한이 주어짐
$ ./test_script # PATH 환경 변수에 현재 디렉토리 (.) 가 포함되어 있지 않으면 ./ 꼭 지정해야함.
# path 경로상에서 이 파일을 찾을 수 없기 때문에 ./ 으로 현재 디렉토리를 명시
I love Linux!
/home/user1/Linux/ch11
$
exit [종료상태]
#!/bin/bash
#test_exit : exit과 $? 를 테스트하는 프로그램
exit 20
# --- 실행 ---
$ ./text_exit # 프로그램 실행
$ echo $? # 변수에 저장된 값 확인
20
$
#!/bin/bash # bash 쉘을 사용하여 스크립트를 실행하도록 지정
# test_sharp: 스스로를 출력하는 스크립트
# 이 스크립트를 시행시키면 자기 자신을 화면에 출력합니다.
# 주석문도 모두 출력되지요.
echo “This line is printed. “
##!/bin/bash
# test_sharp2 : 주석 예제
# 이 스크립트를 실행시키면 주석은 출력되지 않아요.
WHATEVER=65
echo 이 부분은 출력됩니다.
Exit $WHATEVER # exit 문 실행 $?로 확인가능해요.
#!/bin/bah
# find_script : /bin, /usr/bin 에 있는 쉘 스크립트 검색
cd /bin
file * | grep "script"
cd /usr/bin
file * | grep "script"
$ ./find_script # 실행
변수 : 프로그램에서 처리하는 다양한 정보를 저장하는 곳
종류
지정 방법
쉘 변수 표현식
| 형식 | 의미 |
|---|---|
$name | name의 값을 대체 |
$"name" | name의 값을 대치, 변수 이름이 다른 구문과 인접해 있을 떄 사용 |
${name:-word} | name이 정의되어 있으면 그 값을, 그렇지 않으면 word 값사용 |
${name:=word} | name이 정의되지 않았었거나, 널이라면 word를 대입 하고 그 값을 사용 |
${name:+word} | name이 정의되어 있고, 그 값이 널이 아니면 word 값을 사용 |
${name:?word} | name이 정의되어 있고 널 문자가 아니면 그 값을 사용한다. 그렇지 않으면 word 출력 후 종료 |
: 을 사용하지 않으면 널값을 갖고 있어도 변수가 정의 된 것으로 간주
$ test=coookbook #test 변수에 "cookbook" 문자열 저장
$ echo $test #test 변수값 출력
cookbook
$ echo ${test:-word} #test 변수가 정의되어 있으므로 해당 값 출력
cookbook
$ echo ${test1:-word} #test1 변수가 없으므로 문자열 word 출력
word
$ echo ${test:=word} #test 변수가 정의되어있으므로 해당 값 출력
cookbook
$ echo ${test1:=word} #test1 변수가 없으므로 word 를 그 값으로 저장
word
$ echo ${test1:=word1} #test1 변수가 저장되어 있으므로 그 값 출력
word
$ echo ${test:+word} #test 변수가 정의되어있으므로 word 출력
word
$ echo ${test1:?word} #test 변수가 정의되어있으므로 해당 값 출력
cookbook
$ ^test^test2 #test2 변수가 없으므로 word 출력 후 스크립트 종료
echo ${test2:?word}
-bash: test2: word
$
| 표현식 | 기능 |
|---|---|
${variable%pattern} | variable의 뒤부터 패턴과 일치하는 첫번째 부분을 찾아서 제거 |
${variable%%pattern} | variable 값의 뒤부터 패턴과 일치하는 가장 큰 부분 을 찾아서 제거 |
${variable#pattern} | variable 값의 앞부터 패턴과 일치하는 첫번째 부분을 찾아서 제거 |
${variable##pattern} | variable 값의 앞부터 패턴과 일치하는 가장 큰 부분 을 찾아서 제거 |
# "%" : 뒤에서부터 패턴과 일치하는 최소 부분을 제거 (%%는 최대부분)
$ path1 = "/usr/bin/local/bin"
$ echo ${path1%/bin}
/usr/bin/local
$ echo ${path1%%/bin*} # %% 사용시 지정한 패턴이 변수 값 중간에 있다면,
/usr # 패턴 이후에 임의의 값이 나올 수 있다는 표시로 * 지정해여 한다.
$
# "#" : 앞에서부터 패턴과 일치하는 최소 부분을 제거 (## 은 최대부분)
$ path1 = "/home/user1/.profile"
$ echo ${path2#/home}
/user1/.profile
$ echo ${path2##*/} # ## 을 사용할 때는 패턴 앞에 * 지정
.profile # 이 예는 경로에서 파일명만 추출할 때 사용
$ # */ : 슬래시 앞에 있는 것 다 지우기
$ echo ${#path1}
18
$ echo ${#path2}
20
$
| 명령행 인자 | 의미 |
|---|---|
$0 | 쉘 스크립트의 이름 |
$1 ~ $9 | 명령행에 주어진 첫번쨰 부터 9번쨰까지 인자 |
$(10) | 10번째 인자 |
$# | 전체 인자 개수 |
$* | 모든 인자 |
$@ | $*과 같은 의미 |
"$*" | "$1 $2 $3" |
"$@" | "$1","$2","$3" |
$? | 최근 실행된 명령의 종료값 |

#!/bin/bash
# test_position: 명령행 인자를 테스트
#
echo '$* : ' $* # 모든 인자의 값 출력
echo '$# : ' $# # 전체 인자의 개수 3출력
echo '$@ : ' $@ # 모든 인자의 값 출력
echo $1 $2 $3 # 그냥 출력
set -- # 명령행 인자를 초기화
echo '$* : ' $*
echo '$# : ' $#
echo '$@ : ' $@
echo $1 $2 $3
# -------------------------------
$ chmod +x test_position
$ ./test_position one two three
$* : one two three
$# : 3
$@ : one two three
one two three
$* :
$# : 0
$@ :
$
인용부호 : 쉘 특수문자의 의미를 없애기 위해 사용
test = 100
| 인용 부호 | 기능 | 사용법 |
|---|---|---|
| 작은 따옴표 (' ') | 모든 특수문자들이 해석되는 것을 막음, 그 변수 자체의 문자로 해석 | $ echo '$test' $test |
| 큰 따옴표 (" ") | 변수나 명령의 대체만 허용, 그 변수의 값을 리턴 | $ echo "$test" 100 |
| 역 슬래시 () | 단일 문자가 해석되는 것을 막음 | $ echo $test $test |
명령 대체 : 백쿼터, $() 안에 명령어를 넣어 명령 실행 결과를 문자열로 변환
| 기호 | 사용법 |
|---|---|
| 백쿼터(` `) | $ echo `date` Sunday, April 15, 2012 11:05:06 AM KST |
| $(명령) | $ echo $(date) # 실행된 결과를 변수로 해서 사용 Sunday, April 15, 2012 11:15:11 AM KST |

#!/bin/bash
# 키보드 입력 처리를 테스트 하는 스크립트
read x # 아무 메세지 없이 사용자 입력을 기다림
echo "x : $x" # 사용자가 임의의 값을 입력하면 출력
read x y # 첫 단어는 x, 나머지는 y에 저장
echo "x is $x y is $y" # x,y 값 출력
read -p "input :" # input : 을 출력한 후 입력 기다림
echo "input : $REPLY" # $REPLY 에 자동 저장된 입력값 출력
명령 << TERMINATOR
입력내용
TERMINATOR
#!/bin/bash
# here 문서 테스트. user1에게 메일을 보냄
mail user1 << END
This is a test mail for here document
END

$ a=5
$ echo $a
5
$ let a = 20 # let에서는 공백을 사용하지 못함(!!)
- bash: let: =: syntax error
$ let "a = 20" # 공백을 포함하여면 " " 사용해야 함
$ echo $a
20
$ (( a = 30 )) # (( )) 에서는 공백 사용 가능(!!)
$ echo $a
30
$ a=$a*5 # let 이나 (( )) 을 사용하지 않으면 문자열로 처리(!!)
$ echo $a
30*5
$ echo $((5*6)) # 계산 결과를 바로 출력할 수 있음
30
$ echo $(( ! 2 + 3 * 4)) # 우선순위에 따라 ! 먼저 수행. 2는 0이 됨
12
$ echo $(( 2 << 1)) # 왼쪽 shift 는 *2 와 같음. 2번 shift는 *4
4
$ echo $(( 3 ^ 5 )) # XOR 연산 결과
6
$
#!/bin/bash
# test_if : if 문을 테스트 하는 스크립트
echo "input x : "
read x # x 값을 입력 받음
echo "input y : "
read y # y 값을 입력 받음
if((x<y)) # 조건 명령을 실행하여 그 실행값이
then # 0 이 아니면 then 다음의 명령을 실행
echo "x is less than y"
else # 0 이면 else 다음의 명령을 실행한다.
echo "y is less than x"
fi
# ---------------------------
$ ./test_if
Input x : 100
Input y : 200
x is less then y
$
#!/bin/bash
# test_elif : if-elif 문 테스트
echo "input Score : "
read score # 기본적으로 read 는 문자열로 받는데
if (( $score > 90 )) # (( )) 를 사용하여 숫자로 변형하여 연산을 하고 리턴 값은 True False
then
echo "Your score is great."
elif(( $score >= 80 ))
then
echo "Your score is good."
else
echo "Your score is no good."
fi
# ----------------------------
$ ./test_elif
Input Score : 50
Your score is not good.
$

#!/bin/bash
# test_string : 문자열 테스트 스크립트
echo "Are you OK (y/n) ? "
read ans # ans 변수에 값 저장
if [[ $ans = [Yy]*]] # y로 시작하는 문자열인가
then
echo Happy to hear it # y로 시작하면
else
echo That is too bad # y로 시작하지 않으면
fi


#!/bin/bash
# test_file: 파일 연산자 테스트
echo "파일 이름을 입력하세요 : "
read file
if [[ -G $file ]] # 파일의 그룹 ID 가 스크립트 그룹 ID 와 같은지
then
echo 그룹 ID 가 같습니다.
else
echo 그룹 ID 가 같지 않습니다.
fi
if [[ ! -a $file ]] # 파일이 존재한다면
then
echo 파일이 존재하지 않스빈다. 파일 이름을 다시 확인해주세요
elif [[ -f $file ]]
then
echo 일반 파일입니다.
elif [[ -d $file ]]
then
echo 디렉토리 파일 입니다.
else
echo 특수 파일 입니다.
fi
# -------------------------------
$ ./test_file
파일 이름을 입력하세요 : /dev/null
그룹 ID 가 같지 않습니다.
특수 파일입니다.
#!/bin/bash
# case 테스트 스크립트
echo 명령을 선택하세요 :
read cmd
case $cmd in
[0-9]) # value 1 : 0~9 까지 임의의 숫자
date
;;
"cd" | "CD") # value 2 : cd 또는 CD
echo $HOME
;;
[aA-C]*) # value 3 : 소문자 a, 대문자 A,B,C로 시작하는 임의의 문자열
pwd
;;
*)
echo Usage : 명령을 선택하세요
;;
esac
# --------------------------------
$ ./test_case
명령을 선택하세요 : 5
Sunday, August 19, 2012 12:31:35 AM KST
#!/bin/bash
# test_for: for 테스트 스크립트
for num in 0 1 2
do
echo number is $num
done
# ---------------------------
$ test_for
number is 0
number is 1
number is 2
$
#!/bin/bash
# test_for3: 명령행 인자 처리
for person in $* # 명령인자로 처리한 모든 user1 2 3 에 대해서 한번씩 명령어를 수행
do
mailx $person < letter
echo %{person}에게 메일을 보냈습니다.
done
echo 모든 메일을 보냈습니다.
# ---------------------------
$ ./test_for3 user1 user2 user3
user1에게 메일을 보냈습니다.
user2에게 메일을 보냈습니다.
user3에게 메일을 보냈습니다.
모든 메일을 보냈습니다.
$
#!/bin/bash
# test_while: while 을 이용해 1부터 10까지 합을 구하는 스크립트
count=1
sum=0
while(( count <= 10 ))
do
(( sum += count ))
let count+=1
done
echo 1부터 10까지의 합 : $sum
# ------------------------------
$ test_while
1부터 10까지의 합 : 55
$
#!/bin/bash
# test_until: 지정한 사용자가 로그인하면 알리는 스크립트
echo "로그인 이름: " # 입력 안내문 출력
read person # 유저 이름을 person 에 저장
until who | grep $person # > /dev/null , until : True 가 될떄까지 반복
# 로그인한 계정의 리스트 중에 $person 이라는 사람이 있으면
do
sleep 5 # 유저가 접속 중이 아니면 5초 쉼 (뽑을떄까지 5초씩 기다림?)
done
echo "\007" # 그 사람이 로그인을 했다면 삑 소리 나오도록 beep
# ------------------------------
$ ./test_until
로그인 이름 : hanb
hanb pts/3 Aug 19 01:07 (192.168.0.2)
$
#!/bin/bash
# test_select: 사용자 입력에 따라 pwd,date 명령실행
PS3="명령을 입력하세요 : "
select cmd in pwd date quit # pwd, date, quit 을 메뉴를 만들거 뿌려주기
# 만약 1 을 입력하면 reply 에 1 이 저장되고 cmd 에 pwd 가 저장된다.
do
case $cmd in
pwd)
pwd ;;
date)
date;;
quit)
break;;
*)
echo 잘못 입력하셨습니다. 번호를 선택하세요.
;;
esac
REPLY= # REPLY 변수값 초기화
done
# --------------------------------
$ test_select
1) pwd
2) date
3) quit
명령을 입력하세요 : 1
/export/home/user1/Linux/ch11
1) pwd
2) date
3) quit
명령을 입력하세요 : 3
$
#!/bin/bash
# test_cont: continue 테스트
for person in $(< list) # `cat list`와 동일
# list 라는 파일안에 있는 내용을 array 로 만들어줘서 하나씩 person 에 넣기
do
if [[ $person == user2 ]] then
continue # user2 이면 건너뜀
fi
mailx -s “continue test” $person < letter
echo ${person}에게 메일을 보냈습니다.
done
echo --------------------------
echo 모든 메일을 보냈습니다.
$ mkdir ~/.TRASH
$ function trash {
> mv $* ~/.TRASH # 함수의 넣어진 인자들을 전부 TRASH 디렉토리로 move
> }
$
typeset -f : 함수 리스트 확인 가능
trash()
{
mv $* ~/.TRASH }
$
$ touch a b c
$ ls
a b c
$trash a b c
$ ls
$ ls ~/.TRASH
a b c
$
return [n]
#!/bin/bash
# 함수 리턴 값 테스트
function sum {
typeset sum # 지역변수 정의
(( sum= $1 + $2 ))
return $sum
}
sum $1 $2
echo $1 + $2 = $?
# ------------------------------
$ add 3 5
3 + 4 = 7
$
unset -f 함수명
$ unset -f trash
$ functions
$
$ bash -x test_while + count=1
+ sum=0
+ (( count <= 10 ))
+ (( sum+=count ))
+ let count+=1
+ (( count <= 10 ))
+ (( sum+=count ))
+ let count+=1
+ (( count <= 10 ))
(중략)
+ echo 1부터 10까지의 합 : 55
1부터 10까지의 합 : 55
$
trap 명령 시그널
#!/bin/bash
# test_trap: trap 테스트 스크립트
trap ‘echo “$LINENO : count=$count “ ’ DEBUG
count=1 sum=0
while (( count <= 10 ))
do
(( sum += count ))
let count+=1
done
echo 1부터 10까지의 합 : $sum
# ---------------------------------
$ ./test_trap
6 : count=
7 : count=1
9 : count=1
11 : count=2
12 : count=2
(중략)
9 : count=11
15 : count=11
1부터 10까지의 합 : 55
$



(base) ➜ ex.sh bash test_if
Input x :
# 이런식으로 실행시킬 수 있다.
실행권한이 없기 땜누에 ./test_if 로는 실행이 안됨
따라서 chmode -x test+if 로 실행 권한을 주고


x 옵션을 사용하여 실행되는 코드를 하나하나 확인

과제 2번
