쉘스크립트

사용자 입력 데이터 처리

트리스탄1234 2022. 7. 6. 08:43
728x90
반응형

 

1. Command Line 파라메터 입력

스크립트에 입력 데이터를 전달 하는 방법 중 기본적인 방법은 명령어 라인에 입력 데이터를 직접 전달 하는것입니다. 전달 방법은 아래와 같이 명령어 라인에 직접 전달 하면 됩니다.

$./test 10 20

파라메터 읽기

Bash Shell은 위와 같이 명령어 라인에 입력되는 데이터를 처리 하기 위해 positional parameter라고 하는 특별한 변수를 할당 합니다. 이 변수는 $0 ~ $9번까지 할당이 가능하고 0번은 스크립트 파일의 이름이 저장되고 1번 부터 순차적으로 명령어 라인에 입력된 값들을 저장하게 됩니다.

예제를 하나 만들어 봅시다.

#!/bin/bash

# 명령어 라인에서 데이터 한개 입력 받기.

factorial=1

for (( number = 1; number ‹= $1 ; number++ )) ==> 명령어로 입력된 데이터를 $1에 할당.

do

factorial=$[ $factorial * $number ]

done

echo The factorial of $1 is $factorial

$ ./test1 5

The factorial of 5 is 120

$

명령어 2개를 입력 받는 예제

#!/bin/bash

# 두개의 데이터 입력 받기.

total=$[ $1 * $2 ]

echo The first paramerer is $1.

echo The second parameter is $2.

echo The total value is $total.

$ ./test2 2 5

The first paramerer is 2.

The second parameter is 5.

The total value is 10.

$

스트링도 위와 같은 변수에 명령어 라인에서 입력되어 저장될 수 있습니다. 단 주의할 점은 Shell은 데이터의 구분을 Space로 간주를 하기 때문에 스페이스가 있는 스트링을 입력할 때에는 쌍따옴표나, 따옴표를 사용하여 문자열을 묶어 주어야 됩니다.

스크립트를 작성 하다 보면 변수가 위에서 언급한 $9 이상으로 필요한 경우가 있습니다 .그럴 경우에는 ${10} 이런식으로 아래와 같이 사용을 하면 됩니다.

#!/bin/bash

# 많은 입력 데이터 처리 방법

total=$[ ${10} * ${11} ]

echo The tenth parameter is ${10}

echo The eleventh parameter is ${11}

echo The total is $total

$ ./test4 1 2 3 4 5 6 7 8 9 10 11 12

The tenth parameter is 10

The eleventh parameter is 11

The total is 110

$

프로그램 이름 읽어 들이기

명령어 라인에서 프로그램 이름을 변수로 받을때에는 $0를 사용합니다.

#! /bin/bash

# #0 테스트 하기

echo excuted command is: $0

 

$ ./test1

excuted command is: ./test1

$ /home/hyowon/test1

excuted command is: /home/hyowon/test1

$

가끔은 스크립트 이름만 저장을 하고 싶을 경우가 있을겁니다. 이럴 경우에는 basename 이라는 명령을 사용해서 명령어 라인에 path 경로가 입력이 되더라고 실제 스크립트 파일명만 저장이 되게 할수 있습니다.

위의 예제를 고쳐 보도록 하겠습니다.

#! /bin/bash

# #0 테스트 하기

name=`basename $0`

echo excuted command is: $name

실행을 시켜보면.

$ ./test1

excuted command is: test1

$ /home/hyowon/test1

excuted command is: test1

$

그럼 스크립트 이름을 사용해서 더하기와 빼는 스크립트를 작성해 보겠습니다.

#! /bin/bash

#스크립트 이름을 이용한 스크립트 예제

name=`basename $0`

if [ $name = "plus" ]

then

total=$[ $1 + $2 ]

elif [ $name = "mul" ]

then

total=$[ $1 * $2 ]

fi

echo The result is $total

#

자 그럼 이 스크립트를 복사를 해서 스크립트 이름이 plus와 mul인 두개의 파일을 만들 겠습니다.

$ cp test2 plus

$ cp test2 mul

그럼 명령어 라인에 각각의 입력값을 다르게 해서 실행시켜 보겠습니다.

$ ./plus 3 5

The result is 8

$ ./mul 10 32

The result is 320

그런데 내가 만든 스크립트가 아니라면 데이터를 몇개나 넣어야 될지 모릅니다. 이를 위해 test 조건을 사용하여 다음과 같이 스크립트를 작성할 수 있습니다.

#! /bin/bash

# 데이터 입력값 점검 하기

if [ -n "$1" ] ==> 첫번째 데이터가 있으면

then

echo Hello $1, glad to meet you. ==> 이 구문을 실행하고 없으면

else

echo "Sorry, you didn’t identify yourself." ==> 이 구문을 실행 합니다.

fi

#

실행을 시켜 보면

$ ./test3

Sorry, you didn’t identify yourself.

$ ./test3 10

Hello 10, glad to meet you.

$ ./test3 juliet

Hello juliet, glad to meet you.

반응형

2. 특수 변수 파라메터

Counting 파라메터는 명령어 입력 라인에 몇개의 데이터가 입력이 되었는지 입력 데이터의 갯수를 셀수가 있습니다. 이를 위해서 사용하는 변수는 $# 변수를 사용합니다. 아래의 예제를 한번 봅시다.

#! /bin/bash

# 입력 데이터 갯수를 이용한 스크립트

if [ $# -ne 2 ]

then

echo usage: test4 a b

else

total=$[ $1 + $2 ]

echo total is $total

fi

#

그럼 실행시켜 봅시다.

$ ./test4

usage: test4 a b

$ ./test4 3

usage: test4 a b

$ ./test4 3 4 5

usage: test#! /bin/bash

$ ./test4 3 4

total is 7

여러개의 입력 데이터 중에 마지막값을 선택을 할수 있는 방법은 변수 !#를 사용하는 것입니다.

아래 예를 봅시다.

#! /bin/bash

# 입렫된 마지막 변수 사용하기

values=$#

echo inputted valuses are $values

echo last values\'s is ${!#}

#

실행을 시켜 보면

$ ./test5 10 20 30 100 400

inputted valuses are 5

The values's is 400

$

명령어 라인에 입력되는 파라메터 값 한번에 저장하기.

명령어 라인에 입력되는 여러개의 입력값을 한개의 변수에 저장을 할수가 있습니다. 그 변수로는 $*와 $@이 있습니다. $*는 명령어 라인에 입력된느 모든 파라메터를 하나의 string 형태로 저장을 하고 $@는 명령어 라인에 입력되는 데이터들을 space를 기준으로 분리를 하여 저장을 합니다.

그 차이를 실피기 위해 아래와 같은 예제를 살펴 봅시다.

#! /bin/bash

# $*와 $@의 차이점 구분하기

count=1

for values in "$*"

do

echo "$* parameter #$count = $values"

done

count=1

for values in "$@"

do

echo "\$@ parameter #$count = $values"

count=$[ $count + 1 ]

done

그럼 실행을 시켜 보면

$ ./test6 park kim kang choi chun ha

park kim kang choi chun ha parameter #1 = park kim kang choi chun ha

$@ parameter #1 = park

$@ parameter #2 = kim

$@ parameter #3 = kang

$@ parameter #4 = choi

$@ parameter #5 = chun

$@ parameter #6 = ha

$

위에서 보듯이 $*은 입력되는 모든 데이터를 하나의 문자로 취급을 하고, $@은 각각을 분리하여 저장을 하고 있음을 알수 있습니다.

입력 데이터 이동하기

bash shell에서는 입력되는 데이터를 원하는 위치로 이동을 시킬수가 있는데요, 이때 사용하는 명령어가 shift 입니다. shift의 기본 동작은 변수값을 하나씩 앞으로 당겨 줍니다. 즉 $3의 변수값은 $2로 $2의 값은 $1으로 $1의 값은 버려집니다. 이 shift명령은 입력데이터가 얼마나 되는지 모를때 사용하기 유용 합니다.

#! /bin/bash

# shift 명령어 사용하기.

count=1;

while [ -n "$1" ] ==> 입력되는 첫번째 데이터가 있는경우 do 구문 실행

do

echo "parameter #$count = $1" ==> #count 변수의 값을 출력

count=$[ $count +1 ] ==> count의 번호를 하나 증가

shift ==> 데이터 이동

done

실행을 시켜 보면

$ ./test7 park kang kim choi chun ha ra

parameter #1 = park

parameter #2 = kang

parameter #3 = kim

parameter #4 = choi

parameter #5 = chun

parameter #6 = ha

parameter #7 = ra

$

shift명령어로 특정 위치로 데이터 옮기기

아래의 예제는 shift를 사용해서 특정 위치로 데이터를 옮기는 예제 입니다.

#! /bin/bash

# 특정 위치로 데이터 이동하기

echo "original data is: $*"

shift 2 ==> 입력되는 데이터를 2칸 당깁니다.

echo "shifted data is: $1"

실행을 시켜보면

$ ./test8 park kim kang chun ha ra im

original data is: park kim kang chun ha ra im

shifted data is: kang

3, 옵션과 함께 사용하기

명령어 라인에서 옵션고 함께 사용하면 더욱 유용합니다. 옵션과 함께 사용하는 3가지으 방법을 살펴 보겠습니다.

옵션찾기

한개의 옵션 처리하는 예제 입니다.

#! /bin/bash

#한개의 옵션 처리 하는 예제

while [ -n "$1" ]

do

case "$1" in

-a) echo "found -a option";;

-b) echo "found -b option";;

-c) echo "found -c option";;

*) echo "$1 is not an option";;

esac

shift

done

실행을 해보면

$ ./test9 -a -b -c -d -e

found -a option

found -b option

found -c option

-d is not an option

-e is not an option

$

파라메터로 부터 옵션 분리 하기

Linux Shell에서 명령어 입력 라인으로 부터 입력 되는 데이터를 어디가 옵션의 끝이고 어디가 데이터의 시작인지 구분을 해주는 특수 문자가 있습니다. 그것은 더블 데쉬(--)입니다. Shell은 더블 데쉬를 만나면 그 뒤로는 데어터로 취급을 합니다. 아래 예제를 봅시다.

#! /bin/bash

#더블 데쉬 사용하기

while [ -n "$1" ] ==> 입력되는 첫번때 데어터가 있는 동안 반복

do

case "$1" in

-a) echo "found -a option";; ==> $1의 값이 -a일 경우 실행

-b) echo "found -b option";;

-c) echo "found -c option";;

--) shift ==> 더블 데쉬를 만나면 break로 for구문을 빠져 나가고 count 부터 진행

bresk;;

*) echo "$1 is not an option";;

esac

shift

done

count=1

for values in $@

do

echo "parameter #$count: $valuse"

count=$[ $count + 1 ]

done

실행을 해보면

$ ./test9 -a -b -- test12 park kang ha ra

found -a option

found -b option

parameter #1:

parameter #2:

parameter #3:

parameter #4:

parameter #5:

$

옵션에 추가 데이터 입력 받기

가끔은 옵션에 추가 데이터를 입력 받을 경우가 있습니다. 예를 들면 아래와 같은 입력이 들어올때 -b 옵션인 경우가 그런 경우 이겠지요.

$ ./test1 -a -b test2 -c -d

#! /bin/bash

#추가 입력값이 필요한 데이터 입력 받기

while [ -n "$1" ]

do

case "$1" in

-a) echo " find -a option";;

-b) addpara="$2"

echo "find -b option, with addparm value $addpara"

shift ;;

-c) echo "find -c option";;

--) shift

break;;

*) echo "$1 i s not an option";;

esac

shift

done

coung=1;

for addpara in "$@"

do

echo "parameter #$count: $addpara"

count=$[ $count + 1 ]

done

실행을 시켜 보면 아래와 같이 -b 옵션을 만났을때 뒤의 데이터를 저장을 하고 출력을 하게 만들어 줍니다.

$ ./test1 -a -b test2 -c -b test3 -c -d

find -a option

find -b option, with addparm value test2

find -c option

find -b option, with addparm value test3

find -c option

-d is not an option

$

getopt 명령어 사용하기

명령어 라인에 입력으로 옵션이 조합으로 입력되는 경우가 있습니다. 예를 들면 ls -al과 같이 업션이 여러개 붙여서 쓰는 경우가 많은데요 이 경우에 위와 같은 스크립트 상에서는 처리가 되지 않습니다. 이럴 경우 유영한 명령어가 getopt 입니다. 명령어 사용 구문은 아래와 같습니다.

$getopt option optstring parameter

사용하는 예제를 보면 우선 option에 사용할 옵션들을 나열하고 콜론으로 구분을 해 준다음. optstring에 사용할 옵션들과 파라메터를 정의를 해주면 됩니다. 아래 명령어를 실행을 시켜 보면 옵션 값들로 a,b,c,d를 사용하고

b옵션은 뒤에 파라메터를 하나 가지고, -cd는 각각 -c -d로 구분을 하고 --를 삽입후 뒤에 나오는 2개의 파라메터를 처리 하는것을 볼수가 있습니다.

$ getopt ab:cd -a -b value -cd value2 value3

-a -b value -c -d -- value2 value3

h$

옵션 부분에 선언이 되지 않은 옵션값을 optstring값에 입력을 하게 되면 입력되지 않은 옵션에 대해 에러 메세지가 나타나는데요 이를 무시하고 싶은 경우에는 -q 옵션을 사용해 주면 됩닏.

$ getopt ab:cd -a -b value -cde value2 value3

getopt: 부적절한 옵션 -- 'e'

-a -b value -c -d -- value2 value3

$ getopt -q ab:cd -a -b value -cde value2 value3

-a -b 'value' -c -d -- 'value2' 'value3'

getopt 명령을 스크립트에서 사용하기

현재의 옵션과 파라메터값을 getopt 명령의 출력 형식으로 바꾸는 방법은 set 명령에서 더블 데쉬(--) 변수를 getopt로 변경을 하면 명령어에 입력되는 옵션과 파라메터는 getopt 명령어 형식으로 처리가 됩니다.

위에서 사용한 test1 스크립트에 set명령을 이용한 getopt 형식으로 바꾸는 라인 하나를 추가해 보겠습니다.

#! /bin/bash

#추가 입력값이 필요한 데이터 입력 받기

set -- `getopt -q ab:c "$@"`

while [ -n "$1" ]

do

case "$1" in

-a) echo " find -a option";;

-b) addpara="$2"

echo "find -b option, with addparm value $addpara"

shift ;;

-c) echo "find -c option";;

--) shift

break;;

*) echo "$1 is not an option";;

esac

shift

done

coung=1;

for addpara in "$@"

do

echo "parameter #$count: $addpara"

count=$[ $count + 1 ]

done

자 그럼 명령어 옵션을 붙여서 입력해 보도록 합시다.

$./test1 -ac

find -a option

find -c option

$ ./test1 -a -b value1 -cd value2 value2 value3

find -a option

find -b option, with addparm value 'value1'

find -c option

parameter #: 'value2'

parameter #1: 'value2'

parameter #2: 'value3'

$

getopts 명령어 사용하기

getopt는 발견 된 모든 처리 된 옵션 및 매개 변수에 대해 하나의 출력을 생성하지만 이와 달리 getopts 명령은 기존 쉘에서 파라메터들을 순차적으러 치리를 합니다.

명령어 구문은 아래와 같습니다.

$getopts optstring variable

optstring에 유효한 옵션문자들을 나열 합니다. 그리고 이 옵션들이 파라메터값을 필요로 하는 경우는 콜론으로 구분을 합니다. 그리고 getopt명령에서 -q옵션과 같이 에러 메세지를 없애기 위해 콜론으로 시작을 합니다.

getopts는 2개의 환경변수를 하용하는데요, 그중 하나는 OPTARG 변수이고 이 변수는 옵션의 파레메터로 사용되는 값을 저장 합니다. OPTIND 변수는 파라메터 리스트에서 getopts가 떠난 위치를 저장해 줍니다.

이 변수값을 사용해서 처리 후 다시 마지막 위치로 돌아와 다음 파라메터를 처리 하게 됩니다.

 

아래 예제를 한번 보겠습니다.

#!/bin/bash

# processing options and parameters with getopts

while getopts :ab:cd opt

do

case "$opt" in

a) echo "Found the -a option" ;;

b) echo "Found the -b option, with value $OPTARG";; ==> b 옵션의 파라메터 값을 저장

c) echo "Found the -c option";;

d) echo "Found the -d option";;

*) echo "Unknown option: $opt";;

esac

done

shift $[ $OPTIND - 1 ] ==> OPTIND(getopts의 현 위치)를 처음으로 돌립니다.

count=1

for param in "$@"

do

echo "Parameter $count: $param"

count=$[ $count + 1 ]

done

실행을 시켜 보면

$ ./test20 -a -b test1 -d test2 test3 test4

Found the -a option

Found the -b option, with value test1

Found the -d option

Parameter 1: test2

Parameter 2: test3

Parameter 3: test4

$

4. 표준 옵션들.

리눅스에서 표준화된 옵션들이 있는 그 옵션들은 아래표를 참고 하시기 바랍니다.

5. 사용자 데이터 입력 받기

스크립트를 작성 하는 경우 스크립트를 실행 후에 사용자의 데이터 입력을 기다려야 하는 경우가 있습니다. 이럴때 사용하는 명령으로 read 명령이 있습니다.

read 명령어 예제

#! /bin/bash

#read 명령어 사용예제

echo -n "Enter your name: "

read name

echo "Hello $name, welcome to my program."

실행을 시켜 보면.

$ ./test3

Enter your name: richard row

Hello park hyowon, welcome to my program.

위에서 이름을 입력할때 스페이스를 사용하여 성과 이름을 분리하여 입력 하였지만 출력은 하나의 변수에 저장이 되어 하나의 스트링으로 취급되어 출력되는걸 볼수 있습니다 .만약에 성과 이름을 분리를 하고 싶으면 스크립트를 아래와 같이 수정하면 분리가 가능 합니다. -p 파레메터는 출력된 프롬프트의 메세지를 정의할때 사용 합니다.

#! /bin/bash

#read 명령어 사용예제

read -p "Enter you name" first last ==> 입력되는 성과 이름을 각각 first와 last에 분리하여 저장 합니다

echo "Hello $name, welcome to my program."

read 명령에서 별도의 데이터를 저장할 변수를 지정하지 않으면 환경변수 중에서 REPLY의 변수에 입력되는 값을 저장 합니다.

#!/bin/bash

# testing the REPLY environment variable

read -p "Enter a number: "

factorial=1

for (( count=1; count ‹= $REPLY; count++ ))

do

factorial=$[ $factorial * $count ]

done

echo "The factorial of $REPLY is $factorial"

$ ./test24

Enter a number: 5

The factorial of 5 is 120

$

read 명령어 timeout처리 하기

-t 옵션은 read명령을 실행한 후 사용자가 데이터를 입력 하기까지 기다리는 시간을 지정할 수 있습니다. -t의 값은 초단위로 지정이 가능 합니다. 만약에 timeout이 발생한 경우에는 read 명령은 0이 아닌 exit code를 리턴을 하게 됩니다.

예제 코드( 스크립트를 실행시키고 5초간 아무런 입력을 하지 않는 경우)

#! /bin/bash

# read에 -t 옵션 사용 예제

if read -t 5 -p "please enter you name:" name

then

echo "Hello $name, welcome to my world"

else

echo

echo "Sorry. too sloe!"

fi

위의 스크립트를 실행을 시켜 보면

$ ./test4

please enter you name:

Sorry. too sloe!

$

아래는 사용자로 부터 yes나 no를 입력 받는 경우의 예제 입니다.

#!/bin/bash

# getting just one character of input

read -n1 -p "Do you want to continue [Y/N]? " answer ==> -n1은 입력을 1개의 문자만 허용하개 한다.

case $answer in

Y | y) echo

echo "fine, continue on...";;

N | n) echo

echo OK, goodbye

exit;;

esac

echo "This is the end of the script"

$ ./test26

Do you want to continue [Y/N]? Y

fine, continue on...

This is the end of the script

$ ./test26

Do you want to continue [Y/N]? n

OK, goodbye

$

입력되는 데이터 표시 하지 않기

read 명령을 통해 사용자로 부터 입력 받은 데이터 중에 password라던가 민감한 데이터의 경우에는 모니터에 표시를 하고 싶지 않은 경우가 있습니다. 이경우 -s 옵션을 사용하여 해당 데이터를 표시하지 않게 할수 있습니다.

예를 들면 read -s -p "Enter your password:" pass 와 같이 사용을 하면 사용자가 입력하는 데어터는 모니터에 보이지 않게 됩니다.

파일로 부터 읽어 들이기

read명령을 이용 하여 파일로 부터 데이터를 읽어 들이는 경우 read 명령어는 파일의 한줄씩 읽어들이고 데이터를 모두 읽어 들인 경우 read 명령은 non zero로 exit 코드를 리턴 한다.

#! /bin/bash

# read명령을 이용하여 파일로 부터 데이터 읽어 들이기

count=1

cat test7 | while read line

do

echo "Line $count: $line"

count=$[ $count + 1 ]

done

echo "Finished processing the file"

실행을 해보면

$ ./test5

Line 1: #! /bin/bash

Line 2: yeah this is test script for read

Line 3: is it work or not

Line 4: are you interesting to make scripting

Line 5: 0 5 dkjfks dkjreijfa

Line 6: jkdmnvk dkjiwjkfsj kdjfkjca

Line 7: sjdkfjkzxg

Line 8:

Finished processing the file

$

그럼 오늘은 이만..

 
728x90
반응형

'쉘스크립트' 카테고리의 다른 글

스크립트 제어  (1) 2022.07.06
데이터 표현하기  (2) 2022.07.06
세부 구조적인 Shell 명령어  (1) 2022.07.06
구조화된 명령어들  (1) 2022.07.06
기본 Shell 스크립트 작성  (1) 2022.07.05