ForFour

쉘 스크립트(shell script) 기본 문법 본문

개념 챙기기

쉘 스크립트(shell script) 기본 문법

for_four 2021. 1. 28. 22:11

CLI 환경을 사용하면서 알고 있으면 좋을 만한 쉘 기본 문법들에 대해서 정리해봤습니다.

 

#(sharp)

shell script에서 #은 기본적으로 주석에 쓰입니다. 하지만 다양한 곳에서 혹은 잘 모르지만 영어권에서 #은 number sign의 의미가 있습니다. 그것때문인지 #이 shell에서 숫자의 의미로 작용을 하는 경우가 있는데

첫번째, $#입니다.

shell scipt를 실행할때 인자를 갖는 경우가 있습니다. 그때 $1, $2로 n번째의 인자값을 가져올 수가 있습니다. 이때 $#은 인자의 개수를 의미합니다.

두번째, ${#a[@]}

shell script에서 배열의 길이 len(array)를 얻고 싶을 때 다음과 같은 분법으로 배열의 길이를 얻을 수 있습니다.

 

Hello World

.sh확장자로 파일을 하나 만들어 줍니다. `$ touch fourz.sh`

#!bin/bash
echo "Hello World"

`#!`는 셔뱅이라고 하고 쉘의 경로를 지정해주는 역할을 합니다. 사용할 수 있는 쉘 종류는 `$ cat /etc/shells`를 통해 확인할 수 있고 `$ echo $0`로 현재 사용하고 있는 쉘의 경로도 알 수 있습니다. echo는 print의 기능을 합니다.

 

쉘 스크립트에서는 기본적으로 sh나 bash를 주로 사용합니다. 다른 쉘을 사용해도 문법은 거의 호환이 되니 사용해도 무방합니다.

 

파일 실행하기

파일을 실행하려면 `bash four.sh`혹은 `sh four.sh`로 실행하면 됩니다. 명령어 없이 파일을 실행시키려면 실행 권한이 필요한데 아마 파일을 처음 생성하면 실행 권한이 주어져있지 않을 겁니다.  파일에 `chmod`로 실행 권한을 준 후 `./fourz.sh`로 파일을 실행할 수 있습니다.

파일 권한에 대한 내용은 이전 포스트를 참고하세요. [운영체제] 파일 권한(chmod)

 

[운영체제] 파일 권한(chmod)

파일 권한 리눅스는 파일 또는 경로에 각각의 권한을 설정할 수 있으며 기본적으로 권한 값을 가지게 됩니다. 리눅스를 사용하면 "drwxr-xr-x" 이런 형태의 문자열을 보게 됩니다. 보통은 "ls -al" 명

fourz.tistory.com

변수 사용하기

쉘에서는 C언어, Java처럼 미리 변수를 선언해줄 필요는 없습니다.

1. 변수 선언하기
`$ foo=1`의 형태로 변수를 선언할 수 있고 대신 중간에 공백이 있으면 안됩니다.

2. 변수 읽고 사용하기
변수를 사용자에게 입력받을 때는 read를 사용합니다. `$ read foo`
변수를 사용할 때는 $(달러) 문자를 앞에 붙여서 `$ echo $foo`과 같이 사용합니다.
다른 변수의 값을 대입할 때는 $문자를 사용하지 않고 `foo=bar`와 같이 사용합니다.

3. 변수 확인, 해제
선언한 변수를 확인하고 싶다면 `set | grep foo`으로 확인할 수 있고  `unset foo`으로 해제할 수도 있습니다.

4. 연산하기
쉘에서 변수끼리의 연산을 하기 위해서는 expr 명령어가 필요합니다.

echo `expr $foo + $bar`
# or
#$((산술식))의 형태로도 가능
#foo=$(($foo+$bar))
#Or let foo=foo+bar의 형태도 가능

5. 환경변수
쉘을 실행할 때 설정할 수 있는 변수입니다.
$0 = 실행된 쉘 스크립트 이름
$n = 쉘이 실행될 때 넘겨진 n번째 인자
$# = 인자의 개수

 

조건

쉘 스크립트에서 조건 판단은 if와 test 명령을 혼합하여 사용합니다.
c언어처럼 세미콜론(;)을 통해 문장의 끝을 정할 수 있습니다. 조건문의 마지막에는 꼭 fi를 붙여주어야 합니다. 조건문의 형식은 다음과 같습니다.

#if문

if test -f test1
then
echo 'test1 is file'
fi

#-f 는 주어진 인자가 일반 파일일 때 참이 된다.

#test 명령은 [ 조건 ] 로 대체될 수 있다.
if [ -f test1 ]
then
echo 'test1 is file'
fi

if [ -f test1 ]; then
echo 'test1 is file'
fi

#if-else문
if [ -f test1 ]
then
	satement1
else
	statement2
fi

#if-elif문
if [ -f test1 ]
then
	satement1
elif
	statement2
else
	statement3
fi

다음처럼 &&와 ||로 여러 개의 조건을 검사할 수도 있습니다.

# &&(and)와 ||(or)
if [ -f test1 ] && [ -f test2 ]
then
echo 'hello'
if

반복

쉘에서의 반복문에는 for, while, until 세 가지가 있습니다.

#for문은 지정된 범위 안에서 반복을 수행한다.
for foo in var1 var2 var3
do
	statement
done

#while
while [조건문]
do
	statement
done

#until
until [조건문]
do
	statement
done

 

예시 스크립트

git add, commit, push를 동시에 자동화하는 스크립트를 간단하게 작성해보겠습니다.
이 스크립트의 목적은 변경된 파일별로 커밋을 자동으로 하려는 목적에 있습니다.
ohmyzsh를 쓴다면 옆에 활용할 수 있는 git 별칭도 같이 써두었습니다.

Arr=() #Array for modified file or dir
for foo in $(git status) # git status = gst
do
 if [ -d $foo ]; then Arr+=($foo); fi #if dir
 if [ -f $foo ]; then Arr+=($foo); fi #if file

done
for bar in ${Arr[@]}
do
echo $bar;
$(git add $bar) # git add = ga
echo $(git commit -m "add $bar") # git commit -v = gc
done
$(git push) # git push = gp on ohmyzsh

 

추가로 *과 @ 그리고 () bracket 과 {} braces 

(이것은 문법을 보고 제가 판단한 것입니다. 정확한 레퍼런스를 보진 않았습니다.)

제 짧은 경험으로 미루어보아 @, *는 모든의 의미를 담고있다고 볼 수 있을 것 같습니다.
*는 *.txt(모든 텍스트파일)에서의 모든의 의미를 갖고 있다고 생각하면 편할 것 같습니다.
약간의 차이가 있지만 $@, $* 모두 모든 인자를 나타내고 배열에서의 ${a[@]}, ${a[*]}은 모든 배열 값을 의미합니다.

$(command), ${parameters}는 명령어와 인자의 차이인 것 같습니다.
아래의 글로 가면 더 자세한 예시들을 볼 수 있습니다.

저도 처음 shell scipt를 접할 때 일반적인 언어와는 다른 기호사용에 조금 당황했었던 경험이 있는데 이걸 통해서
조금은 막연한 의문점이 사라졌으면 좋겠습니다.

https://superuser.com/questions/935374/difference-between-and-in-shell-script


 

 

참고

tinyurl.com/7co78gm

shaeod.tistory.com/757

recipes4dev.tistory.com/157

w51014.tistory.com/1

blog.gaerae.com/2015/01/bash-hello-world.html

dazemonkey.tistory.com/110

wiki.kldp.org/wiki.php/ShellProgrammingTutorial

dazemonkey.tistory.com/149

dazemonkey.tistory.com/110

 

 

 

*잘못 기재된 부분이 있다면 언제든 댓글달아주세요:)

 

 

Comments