youtu.be/Z2RxGi_hQA8

 

 

 

 

셸 스크립트를 작성하는 방법을 여기서 배움! yay!

 

셸 Shell 은 우리가 사용하는 명령어를 커널에게 전달하는 명령어 해석기임.

가령 disk 에서 /home/eyeballs/README.md 파일을 읽어오라는 명령어(cat /home/eyeballs/README.md) 을

Shell 이 해석하여 커널에게 알려줌.

가장 유명한 셸로 bash shell 이 있음.

 

 

 

 

흔히 사용하는

/etc/profile (centos), 혹은 ~/.bashrc (ubuntu) 에 마지막에 넣어두었던

' export 변수명=값 ' 이 환경변수 라고 함.

환경 변수는 $변수명 으로 접근이 가능.

이를테면 echo $HOME 하면 현재 사용자의 홈 디렉터리 경로가 출력된다.

 

 

 

 

쉘을 작성할 때는 스크립트 가장 위에

#!/bin/bash

혹은

#!/bin/sh

를 넣고 시작함.

sh 가 가장 먼저 만들어진 쉘이고 bash 가 GNU 에서 만들어진 쉘이라고 함.

bash 가 sh 가 갖는 모든 기능을 포괄하면서 추가 기능을 갖고 있으므로 bash 를 사용하는 게 좋겠음.

( 반대로 말하면 sh 는 bash 에서 제공하는 기능을 모두 처리하지 못함 )

 

쉘을 작성할 때는 스크립트 가장 아랫쪽에

exit 0 을 넣어본다.

안 넣어도 스크립트 마무리는 잘 되지만 끝났다는 것을 표시해주기 위해 쓰는 게 좋을 것 같음.넣는 정확한 이유는 모름.

exit 0 은 정상 종료

exit 1 은 비정상 종료

라고 하심.

 

 

실행 할 때는bash [스크립트 파일]혹은 실행 권한을 준 상태에서 프롬프트에서 이름을 바로 넣는./[스크립트 파일] 로 실행 가능.

 

위에 설명 이해 안 가면 지못미

 

 

 

 

변수를 만들고 싶다면

var=abc

var="abc def"

처럼 만듦.

= 좌우로 공백이 없어야 함.

 

변수를 사용할때는 $ 기호를 사용

> echo $var

abc

이런 식.

 

만약 $ 기호 자체를 출력하고 싶다면

작은 따옴표나 앞에 \ 을 사용하면 됨.

> echo '$var'

$var

> echo \$var

$var

이런 식.

 

사용자에게 변수 값을 입력받고 싶다면 read 명령어를 사용

> read var

I am eyeballs #내가 넣은 값이 var 변수에 들어감

> echo $var

I am eyeballs

이런 식.

 

사칙연산을 하고 싶다면 아래 룰을 따름.

변수를 이용하여 사칙연산을 할 때는 작은 따옴표와 expr 을 사용

> result='expr 100 + 200'

> echo $result

300

> result2='expr $result - 100'

> echo $result2

200

이런 식.

 

괄호나 곱하기를 사용한다면 앞에 \ 을 넣어줘야 함.

> result3='expr \( $result2 +22 \) / 2 \* 5'

> echo result3

> 555

이런 식.

 

스크립트를 실행할 때 뒤에 white space 를 기준으로 파라미터를 넣을 수 있음.

bash script.sh a b 123

이런 파라미터들을 스크립트 내에서 $1, $2... 로 접근 가능함.

> text="내가 받은 파라미터는 $1, $2 그리고 $3 이고 개수는 $# 개, 전체 파라미터는 $* 이다"

> echo $text

내가 받은 파라미터는 a, b, 그리고 123 이고 개수는 3 개, 전체 파라미터는 a b 123 이다

이런 식.

 

 

 

 

if 문은 아래와 같이 사용함

if [ 조건 ]
then
  참일 때의 실행문
fi
예)

#!/bin/bash
if [ 1=1 ]
then
  echo "1은 1이다"
fi
exit 0

참고로 조건문의 대괄호 양쪽에는 공백이 무조건 있어야 함.

if [ 조건 ]
then
  참일 때의 실행문
else
  거짓일 때의 실행문
fi
예)

#!/bin/bash
if [ "eyeballs" = "eye" ]
then
  echo "참값"
else
  echo "거짓값"
fi
exit 0

조건문에 비교 연산자는 아래와 같음.

= : 양쪽이 같으면 참

!= : 양쪽이 다르면 참(양쪽이 같으면 거짓)

-n "문자열" : 문자열이 Null(빈 문자열)이 아니면 참 (문자열 길이가 0이 아니면 참)

-z "문자열" : 문자열이 Null(빈 문자열)이면 참 (문자열 길이가 0이면 참)

수식1 -eq 수식2 : 두 수식(혹은 변수)이 같으면 참

수식1 -ne 수식2 : 두 수식(혹은 변수)이 다르면 참

수식1 -gt 수식2 : 수식 1이 수식 2보다 크면 참(>)

수식1 -ge 수식2 : 수식 1이 수식 2보다 크거나 같으면 참(>=)

수식1 -lt 수식2 : 수식 1이 수식 2보다 작으면 참(<)

수식1 -le 수식2 : 수식 1이 수식 2보다 작거나 같으면 참(<=)

!수식 : 수식이 거짓이면 참 (수식에 거짓이 있나??)

-a : && 연산과 동일. and 연산

-o : || 연산과 동일. xor 연산

-d : 파일이 디렉터리라면 참

-e : 파일이 존재하면 참

-L : 파일이 심볼릭 링크면 참

-r : 파일이 읽기 가능하다면 참

-w : 파일이 쓰기 가능하다면 참

-x : 파일이 실행 가능하다면 참

-s : 파일 크기가 0보다 크다면 참

$# -ne 2 : 파라미터 개수($#)가 2개라면 참
파일1 -ef 파일2 : 파일1이 파일2와 같은 파일이라면 참

파일1 -nt 파일2 : 파일1이 파일2보다 최신파일이라면 참
파일1 -ot 파일2 : 파일1이 파일2보다 이전파일이라면 참

 

 

 

 

수식 말고 파일 관련한 기능도 있음

다 적기 힘드니 스샷을 뜸.

 

예를 들어 위와 같이 -f 조건을 넣어서,

fname 에 해당하는 파일이 일반파일이면 가장 위의 5줄을 출력하라 는 의미가 됨.

비슷한 방식으로

-d 조건은 해당 파일이 디렉터리면 참,

-e 조건은 해당 파일이 존재하면 참,

-s 조건은 해당 파일의 크기가 0 이 아니면 참,

...

으로 해석 가능.

 

 

 

 

 

case 문도 사용 가능

#! /bin/bash
case "$1" in
  a)
    echo "a로 시작하는 것은 apple";;
  b)
    echo "b로 시작하는 것은 banana";;
  c)
    echo "c로 시작하는 것은 coconut";;
  d | 
  *)
    echo "그 외 나머지";;
esac
exit 0

위 예제는 첫번째 파라미터 값이 뭐냐에 따라 출력을 다르게 준 것.

a,b,c 에 걸리지 않은 나머지는 가장 마지막 * 로 들어감.

 

아래와 같은 방식으로도 사용 가능

yes, y, U, Yes, YES 뭘 넣든간에 첫번째 case에서 걸리도록 만들었음

또한 n 혹은 N 으로 시작하는 어떠한 입력값을 받아도 두번째 case 에서 걸리도록 만들었음

 

 

 

if 조건문에 and, or 를 아래 예제와 같이 사용 가능.

and 는 -a 혹은 && 로 사용

or 는 -o 혹은 || 로 사용


if [ -f $1 ] && [ -s $1 ] ; then
  head -5 $1
else
  echo "파일이 없거나,
    크기가 0 입니다."
fi
exit 0

 

 

 

for 문은 아래와 같이 사용 가능

for 변수 in 값1 값2 값3 ....
do
  반복할 명령어
done
#! /bin/bash
hap = 0
for i in 1 2 3 4 5
do
  hep=`expr $hap + $i`
done
echo "1부터 5까지 합 : "$hap
exit0

참고로 expr 계산할 때 틸트 사용.

혹은 아래같은 조건문 사용도 가능

for ((i=1; i<=5; i++))
do
  .....
for i in $(seq 1 5)
do
  .....

조건문에 명령어의 결과를 넣을 수 있음.

아래 예제는, ls 로 나오는 목록 중에서 sh 로 끝나는 파일의 이름들을 순서대로 fname 에 넣은 후, 

각 파일의 첫 세 줄을 출력함.

#! /bin/bash
for fname in $(ls *.sh)
do
  head -3 $fname
done
exit 0

 

 

 

 

while 문은 아래처럼 사용

while [ 조건문 ]
do
  반복할 명령어
done
#! /bin/bash
while [ 1 ]
do
  echo "awesome eyeballs!"
done
exit 0

 

위 조건식에 대괄호 양쪽에는 공백이 무조건 있어야 함.

[ 1 ] 조건( 혹은 [ : ] )을 사용한 while문은 무한 반복문임.

 

위 for 문에서 1~5까지의 합을 구하는 반복문을 while 로 만들어 봄

#! /bin/bash
hap=0
i=1
while [ $i -le 5 ] ; do
  hap=`expr $hap + $i`
  i=`expr $i + 1`
done
echo "1부터 5까지 합 : "$hap
exit 0

 

기존의 언어와 다르게, until 문이 존재.

while 문은 조건문이 참이면 동작하지만

until 문은 조건문이 거짓이면 동작함.

문법은 while 문과 동일.

 

 

 

반복문을 제어하기 위해 break, continue, exit 등의 명령어가 있음.

break 는 반복문을 빠져나옴

continue 는 실행 즉시 조건문으로 되돌아감

exit 1 은 실행 즉시 해당 스크립트를 빠져나옴

while [ 1 ] ; do
  break ;;
exit 0
while [ 1 ] ; do
  continue ;;
exit 0
while [ 1 ] ; do
  exit 1 ;;
exit 0

 

 

 

 

함수를 내가 만들어 사용 가능

사용할 때는 그냥 함수 이름만 호출.

함수이름 () {
  함수 내용
  .....
}
#! /bin/bash

myFunction () {
  echo "함수를 만들었다."
  return
}

myFunction  #함수 이름 호출하여 함수 실행
exit 0
#! /bin/bash

myAdder () {
  echo `expr $1 + $2`
}

hap 10 20
exit 0

위처럼 함수 뒤에 차례대로 파라미터를 넣을 수 있고

함수 내에서는 (스크립트에서 파라미터 다룬 방식 처럼) $1, $2, .... 로 접근이 가능

 

함수 내에서 값을 return 할 때는 echo 를 사용할 수 있다고 함.

물론 return 도 사용 가능한데... 반환 값이 1~255 사이의 정수만 된다고 함.

 

echo 로 함수값 반환하는 방법은 아래와 같음

function foo() { echo 'hello'; }
ret=`foo`
echo $ret
function foo() { echo 'hello'; }
ret=$(foo)
echo $ret

반환값 받는 법 : zetawiki.com/wiki/Bash_%ED%95%A8%EC%88%98_%EB%B0%98%ED%99%98_%EA%B0%92_%EB%B0%9B%EA%B8%B0

 

 

 

 

 

eval 을 사용하여 명령문으로 된 문자열을 실행 가능

#! /bin/bash
str="ls -al | grep .sh"
eval $str
exit 0

위의 예제대로라면 목록에서 .sh 가 포함된 모든 파일 이름들이 검색된다.

 

 

 

 

 

 

 

export 를 사용하면, 외부 스크립트에서 선언한 변수를 사용할 수 있게 해줌

이게 뭔 소리임? 하는 사람들 아래 코드 보면 바로 이해가 될 것임.

 

<script.sh>

#! /bin/bash
echo "$var 는 export 라서 이렇게 사용할 수 있음"
exit 0
<export.sh>

#! /bin/bash
export var="변수변수"
bash script.sh
exit 0

 

export.sh 를 실행시키면 내부적으로 export 변수인 var 를 선언하고,

script.sh 를 실행시킴.

script.sh 내부에서는 var 를 선언하진 않았지만

외부 스크립트인 export.sh 에서 export 로 선언하였기 때문에 사용할 수 있음.

 

 

 

 

 

C언어의 printf 같은 함수도 있음.

 

 

 

eval 처럼 명령문으로 된 문자열이 아니라,

그냥 명령문을 실행하고 그 결과를 사용하고 싶다면

$( 명령문 ) 형식으로 사용하면 될 듯.

예를 들어

echo "오늘 날짜는 $(date) 입니다."

 

위처럼 리눅스 명령어를 실행한 후, 그 결과 자체를 파라미터처럼 $1, $2,,, 접근해서 사용하고 싶다면

set 명령어를 사용하면 됨.

 

#! /bin/bash
set $(date) 
echo "오늘은 $1 년 입니다."
echo "오늘은 $2 월 입니다."
echo "오늘은 $3 일 입니다."
echo "오늘은 $4 요일 입니다."

 

date 의 결과가 2020. 09. 24. (금) 02:15:30 KST 처럼 나오는데,

여기서 set 을 사용하면 공백을 기준으로 아래처럼 파라미터화 됨.

2020. 09. 24. (금) 02:15:30 KST 
$1 $2 $3 $4 $5 $6

 

이제 쉽게 접근하면 됨.

 

이 방법을 사용하면, tsv 파일을 하나 head -n 1 로 읽은 다음

set 을 사용하여 필드명을 파라미터처럼 접근할 수 있겠다.

 

 

 

 

shift 를 사용하면, 파라미터 변수들의 위치를 왼쪽으로 한 단계씩 밀어넣음.

만약 내가 script.sh a 1 b 처럼 파라미터를 3개 넣었다고 하자.

 

파라미터가 

a 1 b
$1 $2 $3

처럼 될텐데, shift 를 사용하면 왼쪽으로 한 단계씩 밀림.

이 때 a 는 사라지게 됨.

1 b
$1 $2

shift 를 또 사용하면

b
$1

위와 같이 됨.

예를 들어보자.

 

 

 

 

 

 

 

 

 

+ Recent posts