BASH SHELL 배쉬 셀
Bash 셸
7.1 Bash 쉘 소개
Bash(Borune-again shell)
리눅스, 맥 OS X 등의 운영 체제의 기본 쉘
Bash 문법은 본 쉘의 문법을 대부분 수용하면서 확장
시작 파일(start-up file)
/etc/profile
전체 사용자에게 적용되는 환경 설정, 시작 프로그램 지정
/etc/bashrc
전체 사용자에게 적용되는 별명과 함수들을 정의
~/.bash_profile
각 사용자를 위한 환경을 설정, 시작 프로그램 지정
~/.bashrc
각 사용자를 위한 별명과 함수들을 정의
Bash 시작 과정
시작 파일 예
# .bash_profile
# 사용자의 환경변수 설정 및 시작 프로그램
if [ -f ~/.bashrc ]
then
. ~/.bashrc
fi
PATH=$PATH:$HOME/bin:.
BASH_ENV=$HOME/.bashrc
export USERNAME BASH_ENV PATH
# .bashrc
# 사용자의 별명 설정
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias ll='ls -al --color=yes'
# 시스템 시작 파일 실행
if [ -f /etc/bashrc ]
then
. /etc/bashrc
fli
$ alias
7.2 별명 및 히스토리 기능
별명
alias 명령어
스트링이 나타내는 기존 명령에 대해 새로운 단어를 별명으로 정의
$ alias 단어=스트링
$ alias dir=ls -aF
$ dir
$ alias h=history
$ alias list=ls –l [--color=auto]
현재까지 정의된 별명들을 확인
$ alias # 별명 리스트
dir ls -aF
h history
list ls –l
이미 정의된 별명 해제
$ unalias 단어
히스토리
입력된 명령들을 기억하는 기능
$ history [개수]
기억할 히스토리의 크기
$ echo $HISTSIZE
$ HISTSIZE=100
$ echo $HISTSIZE
로그아웃 후에도 히스토리가 저장되도록 설정
$ echo $HISTFILESIZE
$ HISTFIESIZE=100
$ echo $HISTFILESIZE
재실행
예
$ !! # 바로 전 명령 재실행
$ !999 # 999번 이벤트 재실행
$ !shift # shift로 시작하는 최근 명령 재실행
$ !?.bashrc # .bashrc를 포함하는 최근 명령 재실행
7.3 변수
단순 변수(simple variable)
하나의 값(문자열)만을 저장할 수 있는 변수
$ 이름=단어
$ city=incheon
변수의 값 사용
$ echo $city
incheon
변수에 어느 때나 필요하면 다른 값을 대입
$ city=seoul
한 번에 여러 개의 변수를 생성
$ country=korea city=incheon
단순 변수
한글 스트링을 값으로 사용
$ country=대한민국 city=인천
$ echo $country $city
대한민국 인천
따옴표를 이용하면 여러 단어로 구성된 스트링을 저장
$ address=“인천시 연수구 송도동”
리스트 변수(list variable)
한 변수에 여러 개의 값(문자열)을 저장할 수 있는 변수
$ 이름=( 단어리스트 )
$ cities=(서울 부산 인천)
리스트 변수 사용
리스트 변수 사용 예
리스트 변수 사용
$ echo ${cities[*]}
서울 부산 인천
$ echo ${cities[1]}
서울
리스트의 크기
$ echo ${#cities[*]} # 리스트 크기
3
$ echo ${cities[3]}
리스트 변수에 새로운 도시 추가
$ cities=(${cities[*]} 제주)
$ echo ${cities[3]}
제주
표준입력 읽기
read 명령어
표준입력에서 한 줄을 읽어서 단어들을 변수들에 순서대로 저장
남은 단어들은 마지막 변수에 모두 저장
$ read 변수1, ..., 변수n
$ read x y
Merry Christmas !
$ echo $x
Merry
$ echo $y
Christmas !
변수를 하나만 사용
$ read x
Merry Christmas !
$ echo $x
Merry Christmas !
7.4 지역변수와 환경변수
환경변수와 지역변수
쉘 변수
환경변수와 지역변수 두 종류로 나눌 수 있다
환경 변수는 값이 자식 프로세스에게 상속되며 지역변수는 그렇지 않다
환경변수와 지역변수 예
$ country=대한민국 city=서울
$ export country
$ echo $country $city
대한민국 서울
$ sh
$ echo $country $city
대한민국
$ ^D
$ echo $country $city
대한민국 서울
사전 정의 환경변수(predefined environment variable)
그 의미가 미리 정해진 환경변수들
$ echo 홈 = $HOME 사용자 = $USER 쉘 = $SHELL
홈 = /home/mysung 사용자 = mysung 쉘 = /bin/bash
$ echo 터미널 = $TERM 경로 리스트 = $PATH
터미널 = ansi 경로 리스트 = /bin:/usr/bin:/usr/local/bin
사전 정의 지역 변수(predefined local variable)
#!/bin/bash
# builtin.bash
echo 이 스크립트 이름: $0
echo 첫 번째 명령줄 인수: $1
echo 모든 명령줄 인수: $*
echo 명령줄 인수의 개수: $#
echo 이 스크립트를 실행하는 프로세스 번호: $$
echo 이전 명령의 반환 값: $?
$ chmod +x builtin.bash
$ builtin.bash hello shell
이 스크립트 이름: builtin.sh
첫 번째 명령줄 인수: hello
모든 명령줄 인수: hello shell
이 스크립트를 실행하는 프로세스 번호: 12345
이전 명령의 반환 값: 0
7.5 Bash 쉘 스크립트
Bash 스크립트 작성 및 실행 과정
(1) 에디터를 사용하여 Bash 스크립트 파일을 작성한다.
#!/bin/bash
# state.bash
echo -n 현재 시간:
date
echo 현재 사용자:
who
echo 시스템 현재 상황:
uptime
(2) chmod를 이용하여 실행 모드로 변경한다.
$ chmod +x state.bash
(3) 스크립트 이름을 타이핑하여 실행한다.
$ state.bash
if 문
if 문
if 조건식
then
명령어리스트
fi
조건식
test 식
[ 식 ] (반드시 빈칸)
예
if `test $# -eq 1`
if [ $# -ne 1 ]
#!/bin/bash
# wc1.bash 파일명
# 명령줄 인수 개수를 확인하고 wc 명령어를 실행
if [ $# -ne 1 ]
then
echo 사용법: $0 파일
exit 1
fi
file=$1
wc $file
$ wc1.bash
사용법: wc1.bash 파일
$ wc1.bash wc1.bash
11 30 159 wc1.bash
if-then-else
if-then-else 구문
if 조건식
then
명령어리스트
elif
명령어리스트
else
명령어리스트
fi
#!/bin/bash
# count1.bash [디렉터리]
# 대상 디렉터리 내의 파일과 서브디렉터리 개수를 프린트
if [ $# -eq 0 ]
then
dir="."
else
dir=$1
fi
echo -n $dir 내의 파일과 서브디렉터리 개수:
ls $dir | wc -l
$ count1.bash
. 내의 파일과 서브디렉터리 개수: 17
7.6 식
비교 연산
산술 비교 연산
문자열 비교 연산
문자열 비교 연산자
#!/bin/bash
# reply.bash
# 계속 여부를 입력받아 프린트한다
echo -n "계속 하겠습니까 ? "
read reply
if [ $reply == "yes" ]
then
echo 예
elif [ $reply == "no" ]
then
echo 아니오
fi
$ reply.bash
계속 하겠습니까 ?아니오
아니오
#!/bin/bash
# reply2.bash
# 계속 여부를 입력받아 프린트한다
echo -n "계속 하겠습니까 ? "
read reply
case $reply in
y*)
echo 예 ;;
n*)
echo 아니오
esac
$ reply2.bash
계속 하겠습니까 ?아니오
아니오
파일 관련 연산
파일 관련 연산: 예
if [ -e $file ]
then # $file이 존재하면
wc $file
else # $file이 존재하지 않으면
echo "오류 ! 파일 없음“
fi
if [ -d $dir ]
then
echo -n $dir 내의 파일과 서브디렉터리 개수:
ls $dir | wc -l
else
echo $dir\: 디렉터리 아님
fi
부울 연산자
조건식에 부울 연산자 사용
! 부정(negation)
&& 논리곱(logical and)
|| 논리합(logical or)
# $file이 일반 파일이고 쓸 수 있으면
if [ -f $file ] && [ -w $file ]
then
uptime > $file
fi
if [ ! -e $file ]
then # $file이 존재하지 않으면
echo $file : 파일 없음
fi
if [ ! -d $file ]
then # $dir이 디렉터리가 아니면
echo $file : 디렉터리 아님
fi
산술 연산
• 본쉘의 산술 연산
$ a=2+3
$ echo $a
$ a=`expr 2 + 3` # 반드시 빈칸
• 콘쉘의 let 명령어를 이용한 산술 연산
$ let 변수=수식
$ let a=2*3
$ echo $a
6
$ let a=$a+2
$ echo $a
8
$ let a*=10
$ let b++
산술 연산자
변수 타입 선언
변수 타입 선언: declare
$ declare -i a # a는 정수형 변수
$ a=12
$ a=a+1 # let 필요 없음
$ echo $a
$ a=12.3 # 오류 메세지
bash: 12.3: syntax error in expression (error token is ".3")
$ declare -r b=23.4 # 읽기 전용
$ b=23.5 # 오류 메세지
bash: b: readonly variable
7.7 제어구조
Bash 제어구조
조건
if
스위치
case
반복
for, while, until
조건문
if 조건식
then
명령어리스트
fi
if 조건식
then
명령어리스트
else
명령어리스트
fi
중첩 조건문
if 조건식
then
명령어리스트
elif 조건식
then
명령어리스트
else
명령어리스트
fi
중첩 조건문: 예
#!/bin/bash
# score1.bash
# 점수에 따라 학점을 결정하여 프린트
echo -n '점수 입력: '
read score
if (( $score >= 90 ))
then
echo A
elif (( $score >= 80 ))
then
echo B
elif (( $score >= 70 ))
then
echo C
else
echo 노력 요함
fi
$score1.bash
점수 입력: 99
A
스위치
case 단어 in
패턴1) 명령어리스트;;
패턴2) 명령어리스트;;
...
*) 명령어리스트;;
esac
#!/bin/bash
# 사용법: score2.bash
# 점수에 따라 학점을 결정하여 프린트한다.
echo -n '점수 입력: '
read score
let grade=$score/10
case $grade in
"10" | "9") echo A;;
"8") echo B;;
"7") echo C;;
*) echo 노력 요함;;
esac
반복문: for
for 구문
리스트의 각 값에 대해서 명령어들을 반복
for 이름 [in 단어리스트]
do
명령어리스트
done
#!/bin/bash
# for.bash
for color in red yellow green blue
do
echo one color is $color
done
#!/bin/bash
# invite.bash
# 저녁 초대 메일을 보낸다.
invitee=(mysung stu s1234567) # 자기 ID 추가
for person in $invitee # Debug!
do
echo “오늘 저녁식사에 초대합니다 MYS" | \
mail "${person}"
# mail "${person}@naver.com"
Done
$ su – stu
암호:
모든 명령줄 인수 처리
모든 명령줄 인수 처리
for file [ in $* ]
do
...
done
단어 리스트가 없으면 대신 $@
#!/bin/bash
# perm1.bash 파일*
# 파일의 사용권한과 이름을 프린트한다
if [ $# -eq 0 ]
then
echo 사용법: $0 파일*
exit 1
fi
echo "사용권한 파일"
for file in $*
do
if [ -f $file ]
then
fileinfo=`ls -l $file`
perm=`echo "$fileinfo" | cut -d' ' -f1`
echo "$perm $file"
fi
done
반복문: while & until
while 문
조건에 따라 명령어들을 반복 실행
while 조건식
do
명령어리스트
done
until 문
조건에 따라 명령어들을 반복 실행
until 조건식
do
명령어리스트
done
#!/bin/bash
# power.bash
# 2의 1승부터 10승까지 프린트
let i=2
let j=1
while (( $j <= 10 ))
do
echo '2 ^' $j = $i
let i*=2
let j++
done
#!/bin/bash
# power.bash
# 2의 1승부터 10승까지 프린트
let i=2
let j=1
until (( ))
do
echo '2 ^' $j = $i
let i*=2
let j++
done
while .vs. until
#!/bin/bash
# while.bash
x=1
while [ ]
do
echo x=$x
x=`expr $x + 1`
done
#!/bin/bash
# until.bash
x=1
until [ $x -gt 3 ]
do
echo x=$x
x=`expr $x + 1`
done
menu.bash
#!/bin/bash
# 사용법: menu.bash
# 메뉴에 따라 해당 명령어를 실행한다.
echo 명령어 메뉴
stop=0
while (($stop == 0))
do
cat << MENU
d : 날짜 시간
l : 현재 디렉터리 내용
w : 사용자 보기
q : 끝냄
MENU
echo -n '? '
read reply
case $reply in
"d") date;;
"l") ls;;
"w") who;;
"q") stop=1;;
*) echo 잘못된 선택;;
esac
done
$ menu.bash
명령어 메뉴
d : 날짜 시간
l : 현재 디렉터리 내용
w : 사용자 보기
q : 끝냄
? d
2012년 2월 23일 목요일 오후 07시 33분 27초
d : 날짜 시간
l : 현재 디렉터리 내용
w : 사용자 보기
q : 끝냄
? q
함수
함수 정의
함수이름()
{
명령어리스트
}
함수 호출
함수이름 [매개변수]
#!/bin/bash
# lshead.bash
lshead() {
echo "함수 시작, 매개변수 $1"
date
echo "디렉터리 $1 내의 처음 3개 파일만 리스트"
ls -l $1 | head -4
}
echo "프로그램 시작"
lshead /tmp # 명령줄 인수로 수정하세요
exit 0
$ lshead.bash
프로그램 시작
함수 시작, 매개변수 /tmp
2012. 10. 31. (수) 14:10:10 KST
디렉터리 /tmp 내의 처음 3개 파일만 리스트
합계 968
-rw-r--r--. 1 s2701367 ul2011a 2 10월 21 02:15 1.c
-rw-r--r--. 1 s2701346 ul2011a 3 10월 23 04:21 12.c
-rw-r--r--. 1 s201101608 ul2011a 298 10월 21 21:39 2.5.c
7.8 고급 기능
디버깅
$ bash -vx 스트립트 [명령줄 인수]
#!/bin/bash
# menux.bash 오류 있는 프로그램
echo 명령어 메뉴
명령어 메뉴
stop=0
while (($stop == 0))
do
cat << MENU
echo -n '? '
read reply
case $reply in
"d") date;;
"l") ls;;
"w") who;;
"q") stop=1;;
*) echo 잘못된 선택;;
esac
done
$ bash -vx menux.bash
#!/bin/bash
# 사용법: menu.bash
# 메뉴에 따라 해당 명령어를 실행한다.
echo 명령어 메뉴
+ echo $'\270\355\267\311\276\356' $'\270\336\264\272'
명령어 메뉴
명령어 메뉴
+ $'\270\355\267\311\276\356' $'\270\336\264\272'
./menux.bash: line 5: 명령어: command not found
stop=0
+ stop=0
while (($stop == 0))
do
cat << MENU
echo -n '? '
read reply
case $reply in
"d") date;;
"l") ls;;
"w") who;;
"q") stop=1;;
*) echo 잘못된 선택;;
esac
done
./menux.bash: line 20: warning: here-document at line 9 delimited by end-of-file
(wanted `MENU')
./menux.bash: line 21: syntax error: unexpected end of file
shift
shift 명령어
명령줄 인수[리스트 변수] 내의 원소들을 하나씩 왼쪽으로 이동
shift [리스트변수]
$ chmod +x perm2.bash
$ ./perm2.bash *
$ ./perm2.bash p*
#!/bin/bash
# perm2.bash 파일*
# 파일의 사용권한과 이름을 프린트
if [ $# -eq 0 ]
then
echo 사용법: $0 files
exit 1
fi
echo "허가권 파일"
while [ $# -gt 0 ]
do
file=$1
if [ -f $file ]
then
fileinfo=`ls -l $file`
perm=`echo "$fileinfo" | cut -d' ' -f1`
# perm=`ls -l $file | cut -d' ' -f1`
echo "$perm $file"
fi
shift
done
디렉터리 내의 모든 파일 처리
디렉터리 내의 모든 파일 처리
해당 디렉터리로 이동
for 문과 대표 문자 *를 사용
대표 문자 *는 현재 디렉터리 내의 모든 파일 이름들로 대치
cd $dir
for file in *
do
...
done
$ chmod +x count2.bash
$ ./count2.bash /tmp
$ ./count2.bash /dev
$ mknod mypipe p
$ ./count2.bash ./
재귀적 반복(recursion)
스크립트도 자기 자신을 호출 가능
어떤 디렉터리의 모든 하위 디렉터리에 대해 동일한 작업을 수행할 때 매우 유용함
반드시 절대경로로 호출
$ chmod +x rhead.bash
$ rm a.out
$ ./rhead.bash ./
#!/bin/bash
# rhead.bash [디렉터리]
# 대상 디렉터리와 모든 하위 디렉터리 내에 있는 파일들의 헤더를 프린트
#if [ $# -eq 0 ]
#then
# echo 사용법: $0 directory
# exit 1
#fi
#if [ ! -d $1 ]
#then
# echo $0\: $1 디렉터리 아님
# exit 1
#fi
cd $1
for file in *
do
if [ -f $file ]
then
echo "========== $file ==========="
head -3 $file
fi
if [ -d $file ]
then
/home/mysung/ulprog/shellprog/rhead.bash $file
fi
done
터미널에서 실행
터미널에서 while 혹은 for 문도 실행
$ for f in *
> do
> echo $f
> done
$ echo $PS2
$ let i=2
$ let j=1
$ while (( $j <= 10 ))
> do
> echo '2 ^' $j = $i
> let i*=2
> let j++
> done
2 ^ 1 = 2
2 ^ 2 = 4
…
2 ^ 10 = 1024
(참고) set
set 옵션
$ set -v (verbose mode)
$ set +v (verbose mode 제거)
$ set -x (실행된 명령에 + +표시, 전달된 매개변수 내용 출력, 디버깅에 좋음)
$ set - (-v와 -x를 무력화 시키고 인수로 매개변수 설정)
$ set -- (double hyphens)로 매개변수 시작 알림
$ set -u (설정되지 않은 변수 만나면 에러 발생)
$ set -k (명령 이름 앞에 적은 것 뿐 아니라, 모든 키워드 인수를 명령의 환경으로 설정)
(예)
$ set - a b c
$ echo $1
$ date
2013. 11. 11. (월) 11:11:11 KST
$ set -- `date`
$ echo $6
KST
$ echo "$@"
2013. 11. 11. (월) 11:11:11 KST
(참고) set
-x 명령 행 옵션으로 실행되는 디버깅 기능
$ cat set.bash
set -vx a.c
ls $1
set -
echo notset=\"$notset\"
echo goodbye $LOGNAME
set -u
echo notset=\"$notset\"
$ set.bash b.c
…?… 실제로 수행된 명령 앞에 ++ 표시
쉘 명령 앞에서 변수 배정 정의하면 그 명령으로 변수 값이 export됨
$ cat myname
echo My name is $name and my argument is $1
$ name=MYS myname Jay
set -k로 매개변수를 주어진 모든 키워드(‘=‘) 인수를 명령의 환경에 위치시킴
$ set -k
$ myname name=MYS Jay
(참고) junk (= 7장 연습문제 2번 해법)
#! /bin/bash
# junk script
# Initialize variables
fileCount=0 # the number of files specified.
listFlag=0 # set to 1 if the list option (-) is used.
purgeFlag=0 # set to 1 if the purge (-p) option is used.
fileFlag=0 # set to 1 if at least one file is specified.
junk=~/.junk # the name of the junk directory.
error ()
{
# Display error message and quit
cat << ENDOFTEXT
echo Dear $USER, the usage of junk is as follows:
echo junk -p means "purge all files"
echo junk -l means "list junked files"
echo junk <list of files> to junk them
ENDOFTEXT
exit 1
}
# Parse command line
for arg in $*
do
case $arg in
"-p")
purgeFlag=1 ;;
"-l")
listFlag=1 ;;
"-*")
echo $arg is an illegal option ;;
*)
fileFlag=1
fileList[$fileCount]=$arg # append to list
let fileCount=fileCount+1 ;;
esac
done
핵심 개념
단순 변수는 하나의 값(문자열)을 리스트 변수는 여러 개의 값 (문자열)을 저장할 수 있다
쉘 변수는 크게 환경변수와 지역변수 두 종류로 나눌 수 있다. 환경 변수는 값이 자식 프로세스에게 상속되며 지역변수는 그렇지 않다
Bash 쉘은 조건, 스위치, 반복 등을 위한 제어구조로 if, case, for, while 등의 문장을 제공한다
Bash 쉘의 식은 비교 연산, 파일 관련 연산, 산술 연산 등을 할 수 있다
'myPPT' 카테고리의 다른 글
일제의 경제 수탈 (1) | 2015.07.06 |
---|---|
지구의 생성 (0) | 2015.07.04 |
사회복지의 역사 in 서양 and 한국 (0) | 2015.06.29 |
중국의 현대시 : 시기별 단계 (0) | 2015.06.26 |
전략캔버스 - 가치곡선 (0) | 2015.06.24 |