[LINUX] 5.셸 스크립트1(변수, 논리구조, 문자열)
📍 해당 게시글은 사물인터넷을 위한 리눅스 기본을 공부하며 정리한 글입니다.
1. 셸 스크립트
1) 셸 스크립트란?
- 응용 소프트웨어를 제어하는 컴퓨터 프로그래밍 언어.
- 셸이나 명령 줄 인터프리터에서 돌아가도록 작성 or 운영체제를 위해
- c++, java 같은 언어랑 비슷하지만 가장 큰 차이점은 스크립트로 작성된 프로그램은 인터프리트만 된다.(컴파일x)
- 사용하는 이유
- 반복 작업을 자동화하고 제거하는데 사용된다
- 시스템 관리자가 백업에 사용
- 시스템 모니터링을 자동으로 수행
2) 작성방법
- 1) 생성
touch [test.sh](http://test.sh)
확장자는 .sh 또는 .bash로 만든다
- 2) 작성
- 스크립트의 시작은 씨뱅(#!)
#! /bin/bash
로 작성을 시작한다. → bash가 파일을 스크립트로 인식하고 실행함!- #은 주석
- 3) 실행
./test.sh
또는bash test.bash
3) 셸 변수
변수는 환경 변수와 지역 변수로 나뉜다. 변수 생성시에는 =등호 앞뒤로 공백이 있으면 안된다!
(공백이 있으면 변수명을 명령어로 인식)
a. 지역변수 생성
변수명=값
- 값으로는 한국어도 가능하고 “한국 서울” 과 같이 문자열로도 저장이 가능하다.
- (bash명령어를 통해 자식 셸을 만들고 지역변수를 출력하고자하면 출력x)
b. 환경변수 생성
env $변수명=값
export 지역변수명
← 이는 지역변수를 환경변수로 전환하는방법
c. 동시 생성과 출력
- 한번에 여러 개의 변수를 생성
country=Korea city=Seoul
세미콜론(;)없이 생성이 가능하다. 물론 있어도 상관없다.
- 한번에 여러 변수 출력
echo $country $city
echo에서는 $를 사용해야 문자가 아닌 변수로 인식한다. (여러 변수를 출력하고자 세미콜론을 쓴다면 이는 문자열로 인식되기에, 그냥 쭉 이어서 작성하면 됨!)
d. 리스트 변수
문자열이 여러 단어를 저장할 수 있는 변수라면 리스트는 여러 문자열,값을 저장할 수 있는 변수이다.
- 생성 방법 :
리스트명=(문자열리스트)
- ex) cities=(서울 부산 목포)
- 사용 방법
- i번째 원소 :
${리스트명[i]}
- 모든 원소 :
${리스트명[*]}
← 와일드카드 * 대신 @ 도 가능 - 원소 개수 :
${#리스트명[*]}
← #을 이용해 원소 개수를 count!
- i번째 원소 :
4) 사전 정의 지역 변수
이름 | 의미 |
---|---|
$$ | 스크립트 실행하는 프로세스 번호 |
$0 | 셸 스크립트 이름 |
$1 ~ $9 | 명령줄 인수 |
$* | 모든 명령 줄 인수 리스트 |
$# | 명령줄 인수의 개수 |
butilin.sh에 아래 스크립트를 작성하고
./butilin.sh hello shell
실행.- 위 실행이 명령줄이 되고, $0은
./butilin.sh
$1은hello
가 된다.
5) 기타 문법
-
echo 개행x : -n 옵션은 개행을 하지않고 “현재시간: date정보”와 같이 출력한다.
echo -n 현재시간: date
-
명령어 열(command sequence) ;
date; who; pwd
를 실행하면 3가지 출력이 순차적으로 실행된다. -
명령어 그룹 ()
(date; who; pwd) > out2.txt
를 하면 명령어 3개의 출력이 txt에 저장된다. - 셸 명령어 : ls, echo, cd, touch, pwd..
- 셀 키워드 : if, else, break, while, then..
6) 셸 스크립트에서의 입력과 출력
read : 키보드로부터 입력
printf : 모니터로 출력
read 변수1.. 변수n
- 표준입력에서 한 줄을 읽고 단어들을 변수에 순서대로 저장
- 여기서 마지막 변수에는 저장되지 않고 남은 단어를 다 저장한다.
옵션
- read -a 리스트명 : 입력값을 리스트 변수에 할당
- read -n 숫자 : 숫자 개수만큼의 단어만 읽어옴
- read -p 문자열 : 문자열을 출력하고 입력을 받음
- read -s : 비밀번호를 입력받기 위한 용도로 입력값이 보이지 않음
- read -t 시간 : 시간(초)만큼 입력을 대기
- 이를 이용해 sleep기능 구현 :
read -t 3 < /dev/zero
- 이를 이용해 sleep기능 구현 :
2. 산술연산
산술연산을 위해 단순히 a=2+3
을 한다면 변수 a에는 2+3이라는 문자열이 저장된다.
이를 위해 let을 이용한 방법과 expr을 이용하는 방법이 있다
1) let
let은 변수에 계산한 값을 저장한다.
let a=2*3 # 6
let a=$a+2 # 8
echo $a
let a++, b-- # let이 없으면 저장이 일어나지 않음!
2) expr
expr에서 가장 조심해야할 점은 공백이다.
expr도 명령어이기 때문에 연산자와 숫자를 구분할 수 있도록 숫자,연산자 사이에 공백이 필수!
다만, 곱셈&나눗셈에는 $(())을 사용해야하는데 이 안에서는 공백이 필수x
또한 괄호 안에서 변수를 사용할 때에는 $를 사용하지 않아도 된다.
#덧셈, 뺼셈 - 소수점 계산은 안됨
expr 20 + 10 #30
expr 20 - 10 #10
#곱셈 - $(())으로 묶어줘야함
expr $((4 * 25)) #100
#나눗셈 - 마찬가지로 $(())사용, 소수점 이하는 버림
expr $((30/7)) #4
#나머지
expr $((30/7)) #2
#삼항연산자
echo $((n==1 ? 90 : 80))
#한 줄에 여러 명령
expr $((n=10, n+=90)) # 100
3) 연산자
a. 연산자
- 사칙 연산자 : +, -, *, /
- 복합 대입 연산자 : +,=, -=, *=, /=, %=
- 비교 연산자 : ==, !=, >, >=, <, <= ← let이 아닌 expr을 사용하면 저장x
-
논리 연산자 : !, &&, ← 이는 [[ ]] 으로 감싸야한다! - 기타 : %, ++, –, 삼항연산자 등
b. 문자 연산자 → if[]와 같이 대괄호 안에서 가능 (())에선 불가능
- -eq : EQual
- -ne : NEgative
- -gt : Greater Than
- -ge : Greater than Equal
- -lt : Less Than
- -le : Less than Equal
3. 제어문(if)
여느 프로그래밍 언어와 같이 if, if ~ else, if ~ elif, case문이 있다.
주의점 : 조건을 적을 때 대괄호[] 를 사용해야하고 대괄호와 조건 사이에는 공백이 필수!
1) if문의 기본 구조
if [ 값1 조건식 값2 ];
then
수행문
fi
2) 콘솔에서 직접 사용
$read score
$ if [ $score -ge 90 ] # -ge 는 >=
> then
> echo "Score : A"
> fi
3) bash 파일에서 사용
if 의 괄호를 [] 또는 (())를 사용할 수 있는데, 차이점이 있다
- (()) 는 수식계산에서 사용되는 느낌이라, 이전 곱하기 예제와 같이 $없이 변수를 사용해도 변수를 인식한다.
- 그러나 [] 를 사용하면 변수에 무조건 $를 붙혀야한다. 안붙히면 문자로 인식해서 아래에 경우 무조건 false를 리턴!
ex1) 등호 연산
ex2) 논리 연산
ex3) 문자열 비교 연산
ex4) 계산기
#!/bin/bash
n1=$1 n2=$3 op=$2 res=0
if [ $op == "+" ]; then
res=`expr $1 + $3`
elif [ $op == "-" ]; then
res=`expr $1 - $3`
elif [ $op == "x" ]; then
res=`expr $((n1 * n2))`
elif [ $op == "/" ]; then
res=`expr $1 / $3`
fi
echo $res
4. Case 문
[기본구조]
case $변수 in
패턴1) 수행문;;
패턴2) 수행문;;
.
.
*) 수행문;; # else와 같은 애
esac # case 거꾸로하여 마침.
[예시]
5. 반복문 for
1) 기본구조
- if 에 then이 굳이 있는 것처럼 여기에도 for에는 do가 존재한다.
- if, case가 fi, esac로 끝난 반면 여기는 done으로 끝난다.
- 파이썬의 문법과 비슷하게 for i in 를 사용하는데, 여기서 반복될 숫자끼리는 공백이 존재.
for 변수 in 1 2 3 4 .. n
do
수행문
done
2) 반복될 숫자
파이썬에서는 for i in range(n) 또는 (start, end, step) 또는 for i in list로 인자를 받았다.
위처럼 1 2 3 4 .. n은 리스트와 같은 방법이라 보면 된다.
그렇다면 range(n)과 같은 기능은 없을까? 있다.
{start..end}
- 이는 n부터 m까지의 숫자를 만든다.(m포함)
- ex) for i in {1..9} # 1~9까지 숫자
{start..end..step}
- 이는 start부터 step만큼 더하며 end까지의 숫자를 만든다.
- ex) for i in {0..10..2} # 짝수만!
3) 명령줄 인수 처리
파일실행 시 입력받은 인수($*)를 for문의 인자로 사용하려면?
ex) 홀수 2단
# 다음과 같이 파일 실행 : ./fordodone.sh 1 3 5 7 9
#!/bin/bash
for i in $*
do
echo 2 x $i = `expr $((2*$i))`
done
6. 반복문 while
1) 기본구조
while 조건식
do
수행문
done
2) 예제-2단
#!/bin/bash
i=1
while (( i <= 9 ))
do
echo 2 x $i = `expr $((2 * $i))`
let i++
done
7. 문자열 처리
1) 출력
- echo $str
- echo ${str}
- echo “$str”
2) 부분 출력
출력방법 : ${문자열명:시작인덱스:출력갯수}
echo ${str:2}
는 3번째 문자부터 끝까지 출력(뒤에 갯수 생략시 끝까지)echo ${str:2:5}
는 3번째 문자부터 5개의 문자 출력
3) 문자열 합치기
- str=$a$b$c
4) 문자열 부분 삭제
그냥 변수 해제는 unset 변수명
이고 부분삭제는 #과 %을 이용한다.
str="Hello, world!"
echo ${str#"Hello"} # #은 문자열의 "앞"에서 일치하는 (가장 짧은) 부분 문자열을 삭제. ##은 가장 긴
echo ${str%"world!"} # %는 문자열의 "뒤"에서 일치하는 (가장 짧은) 부분 문자열을 삭제. %%은 가장 긴
5) 문자열 연산
a. 연산자
옵션 같이 생겼지만 0,1을 리턴하는 연산자임
파일 관련 연산자 | 의미 |
---|---|
-a 파일 or -e 파일 | 파일이 존재하면 참 |
-r 파일 | 읽을 수 있으면 참 |
-w 파일 | 작성할 수 있으면 참 |
-x 파일 | 실행할 수 있으면 참 |
-f 파일 | 일반 파일이면 참 |
-d 파일 | 파일이 디렉토리면 참 |
-s 파일 | 크기가 0보다 크면 참 |
b. 사용예제 - 파일의 유무 파악
#!/bin/bash
file=$1
if [ -e $file ]; then
wc $file
else
echo "파일없음"
fi
댓글남기기