블로그 이미지
OSSW(Open Source System SoftWare

calendar

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Notice

2014. 5. 14. 08:37 3. OS이야기/03. Shell Script

이번 글에서는 expect 스크립트에 대한 예제를 통해 이해를 돕는 시간을 갖도록 하겠습니다.

 

(2) 예제


#!/bin/expect


set target "[lindex $argv 0]"
set rootid "[lindex $argv 1]"
set oldpwd "[lindex $argv 2]"
set newpwd "[lindex $argv 3]"
spawn telnet $target
expect -timeout 5 "*ogin:"
send "$rootid\n"
expect -timeout 5 "*assword:"
send "$oldpwd\n"
sleep 2
expect -timeout 5 "#|>"
send "passwd\n"
expect -timeout 5 "New password:"
send "$newpwd\n"
expect -timeout 5 "Re-enter root's new password:"
send "$newpwd\n"

expect eof


    a. 내부변수 선언 및 외부변수 세팅

#!/bin/expect


set target "[lindex $argv 0]"
set rootid "[lindex $argv 1]"
set oldpwd "[lindex $argv 2]"

set newpwd "[lindex $argv 3]"


set 명령은 내부변수를 선언하기 위한 명령어입니다.

 

set target [변수값] 이라고 하면 target 이란 변수를 생성하여 '변수값'을 할당하겠다는 뜻이지요.

 

변수값 자리에 문자열이나 숫자같은 고정값을 하드코딩해 주어도 되지만, 여기서는 외부로부터 입력 변수를 받아 처리하기 위해 "[lindex $argv 0]" 이란 값을 사용했습니다.

 

외부변수로 입력된 값중에 제일 첫번째 값을 가져다가 target 변수에 세팅하겠다는 것입니다.

 

rootid, oldpwd, newpwd 등도 외부변수로 입력된 값중에 각각 두번째, 세번째, 네번째 값을 가져다가 세팅하게 됩니다.

 

    b. 실행 서비스 설정


spawn telnet $target


spawn 명령을 통하여 target 시스템에 접근할 서비스를 telnet 으로 세팅합니다.

 

target 변수에는 IP address 혹은 /etc/hosts 파일에 도메인 세팅이 되어 있는 경우 hostname이 들어오게 되겠죠.

 

    c. 패스워드 변경 수행


expect -timeout 5 "*ogin:"                                     // '*ogin:' 문자열이 뜨기를 5초간 기다림
send "$rootid\n"                                                    // rootid 변수에 할당된 값을 보내고 엔터(\n)를 누름
expect -timeout 5 "*assword:"                              // '*assword:' 문자열이 뜨기를 5초간 기다림
send "$oldpwd\n"                                                  // oldpwd 변수에 할당된 값을 보내고 엔터(\n)를 누름
sleep 2                                                                  // 2초간 waiting
expect -timeout 5 "#|>"                                        // '#'이나 '>' 문자열이 뜨기를 5초간 기다림
send "passwd\n"                                                   // passwd 명령을 보내고 엔터(\n)를 누름
expect -timeout 5 "New password:"
send "$newpwd\n"
expect -timeout 5 "Re-enter root's new password:"

send "$newpwd\n"



expect 명령을 사용하여 'ogin:' 으로 끝나는 문자열을 기다립니다.

 

시스템마다 로그인하려 할 때, 소문자로 'login:' 이 뜨는 경우도 있고 대문자로 'Login:' 이 뜨는 경우도 있어 제일 앞을 '*(asterisk)' 로 처리했습니다.

 

-timeout 5 옵션은 '*ogin:' 이란 문자열이 뜨기를 5초동안 기다리겠다는 것입니다.

 

네트워크의 성능에 따라 시스템에 접속할 때 로그인 프롬프트가 뜨는 시간이 조금씩 다르기 때문에 최소 5초 정도의 여유를 주는 것이 좋습니다.

 

5초 이후에도 해당 문자열이 뜨지 않으면 다음에 나오는 send 명령을 그냥 수행시켜 버립니다.

 

expect -timeout 5 "#|>" 명령 구문은 로그인 후에 해당 시스템의 프롬프트가 떨어지길 기다리고, 그 프롬프트의 제일 마지막 문자열이 '#' 이나 '>' 이길 기다립니다.

 

예제에서는 '#' 과 '>' 만 나열하였지만, 혹시나 프롬프트에 '$' 나 ']' 와 같은 다른 문자열이 마지막에 들어가 있다면 이러한 문자열들도 expect 명령 구문에 포함시켜야 합니다.

 

    d. expect 스크립트 종료 선언


expect eof



expect eof 명령 구문을 사용하여 expect 스크립트를 명시적으로 종료합니다.

 

해당 구문을 사용하지 않을 경우, 스크립트가 정상 종료하지 않은 상태로 남아있게 되어 Ctrl + c 명령 등을 통해 강제 종료해야 합니다.

 

이렇게 expect 스크립트를 모두 작성하였다면 이제 실행해야겠죠?

 

    e. expect 실행


./aix_change_pwd.exp 192.168.63.1 root root password



expect 스크립트의 확장자는 .exp 로 하시면 됩니다.

 

위와 같이 input 변수를 주고 실행한다면 192.168.63.1 IP를 가진 시스템에 root 계정으로 접근하여 기존 패스워드인 root 를 password 로 바꾸게 됩니다.

 

막상 알고보면 별거 없는데 제가 말주변이 없어서 설명을 좀 어렵게 적어놓은 듯 싶네요..;;;;

 

아주 기본적인 예제에 대해서만 설명해 놓았으나, expect 스크립트에도 bash 나 ksh 처럼 if문이나 for문 등을 사용할 수 있습니다.

posted by 박현명

댓글을 달아 주세요

2014. 4. 29. 14:09 3. OS이야기/03. Shell Script

#!/bin/sh

if [ -d $1 ]; then

        cd $1


        if [ -f $2 -a -s $2 ]; then


                echo $2' is file and has contents more than one character.'

 

                array=`cat $1/$2`

 

                for day in ${array}; do

                    if [ -n ${day} ]; then

                        if [ ${day} == "Fri" -o ${day} == "Sat" ]; then

                            echo ${day}' is very happy day!!'
                        else
                            echo ${day}' is gloomy day.'

                        fi
                    fi

                done


        else
                echo $2' is not file or has zero character.'
        fi

fi


앞서 if문 예제 글에서 보여 드렸던 예제 스크립트보단 짧은 스크립트이지만 설명의 편의를 위해 크게 if문과 for문으로 나누어 설명 드리도록 하겠습니다.


 

1) 첫 번째 섹션 - if문 


if [ -d $1 ]; then                             // 첫 번째 매개변수 값이 디렉토리라면,

        cd $1                                     // 해당 디렉토리로 이동


        if [ -f $2 -a -s $2 ]; then        // 두 번째 매개변수 값이 파일(-f)이고 그 파일이 내용을 가지고 있다면(-s),


                echo $2' is file and has contents more than one character.'

 

                array=`cat $1/$2`       // array라는 변수에 두 번째 매개변수인 파일에서 읽어들인 내용을 할당

 

                for day in ${array}; do      // for문 시작

                    ~

                done                                  // for문 종료


        else                     // 두 번째 매개변수 값이 파일이 아니거나 그 파일이 아무런 내용도 가지고 있지 않다면,
                echo $2' is not file or has zero character.'
        fi

fi



라인별 설명은 위 내용을 참조하시면 되겠고,

 

if문의 내용을 한 문장으로 표현하자면,

 

두 번째 매개변수 값이 파일이고 내용을 가지고 있을 경우엔 for문을 실행시켜 원하는 결과를 얻을 것이고, 그렇지 않다면 echo로 그에 대한 내용만 화면에 보여주겠다는 것입니다.

 

if문과 관련해선 앞선 글들에서 자세히 설명해 놓았으니 참고하시면 될 것 같습니다.

 


2) 두 번째 섹션 - for문 


for day in ${array}; do

    if [ -n ${day} ]; then

        if [ ${day} == "Fri" -o ${day} == "Sat" ]; then

            echo ${day}' is very happy day!!'
        else
            echo ${day}' is gloomy day.'

        fi
    fi

done



array라는 변수에 할당된 값이 파일이고 내용을 가지고 있다는 if문을 통과하였다면 for문을 실행하겠죠?

 

그렇다면 이 array 변수를 for문에 집어넣고 이제 띄어쓰기 단위로 구분된 단어 하나하나를 끄집어 내어 day라는 변수에 할당합니다.

 

if문 안의 -n 옵션은 변수의 내용이 null이 아닌지를 판별하는 옵션이므로 day에 할당된 변수값이 null일 경우, 즉 파일의 끝에 도달했을 경우에는 if문을 실행하지 않겠죠.

 

그 다음 if문은 굳이 설명 드리지 않아도 아실 거라 생각됩니다.

 

물론 위 스크립트를 실행시키려면 다음과 같은 샘플 파일이 OS 디렉토리 어딘가에 존재해야만 스크립트 실행 시 매개변수로 넣어줄 수 있겠죠.


# cat /tmp/test.txt

Sun Mon Tue Wen Thu Fri Sat



그리고 다음과 같이 실행시키시면 됩니다.


./ForTest.sh /tmp ForTestResult.txt



이상 for문에 대한 간단한 예제였습니다.


posted by 박현명

댓글을 달아 주세요

2014. 4. 22. 13:12 3. OS이야기/03. Shell Script

#!/bin/sh

if [ -d $1 ]; then

        cd $1

        ##### Example 1. Test Operator
        if [ -f $2 ]; then
                echo $2' is file.'
                printf $2' is file.'\\n > $1/$2
        else
                echo $2' is not file.'
                touch $1/$2
                printf $2' file is created.'\\n > $1/$2
        fi

        ##### Example 2. Arithmetic Comparison Operator
        if [ $3 -gt 1 ]; then
                echo $3' is greater than 1.'
                printf $3' is greater than 1.'\\n >> $1/$2
        elif [ $3 -eq 1 ]; then
                echo $3' is equal to 1.'
                printf $3' is equal to 1.'\\n >> $1/$2
        else
                echo $3' is less than 1.'
                printf $3' is less than 1.'\\n >> $1/$2
        fi

        ##### Example 3. String Comparison Operator
        if [ $4 == "BMW" -o $5 == "Martiz" ]; then

                if [ $4 == "BMW" ]; then
                        echo $4' is very expensive car.'
                        printf $4' is very expensive car.'\\n >> $1/$2
                fi

                if [ $5 == "Martiz" ]; then
                        echo $5' is twins transformer.'
                        printf $5' is twins transformer.'\\n >> $1/$2
                fi

        else

                echo 'Both '$4' and '$5' are not mine.'
                printf 'Both '$4' and '$5' are not mine.'\\n >> $1/$2

        fi

fi


위와 같이 Shell Script를 작성하니 조금 복잡해 보이긴 하지만 50줄도 안되는 아주 간단한 예제입니다.

 

스크립트에 문단이라는 국어적 표현이 맞을지 모르나, 문단별로 나누어서 설명 드리도록 하겠습니다.

 

먼저 위 예제 스크립트는 외부로부터 변수를 받아 처리하기 위해 스크립트 내부적으로『 위치 매개변수($1, $2, $3, ..) 』를 사용하고 있습니다.

 

그리고 제일 첫 번째 라인은 해당 Shell Script 파일을 어떤 Shell로 처리할 것인지를 선언하는 부분입니다.


#!/bin/sh



다들 아시겠지만 Shell에는 bash, ksh, csh, tcsh 등 여러 종류가 있는데, 해당 OS에서 사용 가능한 Shell 이 어떤 것들이 있는지를 확인해 보고 싶다면 bin 디렉토리로 이동하여 다음과 같은 명령어를 수행시켜 보면 됩니다.


# ls *sh*


또한, 현재 접속한 터미널에서 사용하는 기본 Shell이 무엇인지 확인하려면, 다음의 명령어를 수행합니다.

# echo $SHELL


저의 예제는 ksh 또는 bash Shell 기준으로 만들어졌습니다.

 

이렇게 선언부를 간단히 처리하고 본격적인 Shell Script를 작성하시면 됩니다.

 


1) 첫 번째 문단


if [ -d $1 ]; then                                                   // 첫 번째 매개변수값이 디렉토리라면,

        cd $1                                                           // 해당 디렉토리로 이동

        ##### Example 1. Test Operator              // 주석
        if [ -f $2 ]; then                                           // 두 번째 매개변수값이 파일이라면,
                echo $2' is file.'                                   // '$2 is file.' 이라는 문장을 echo 한다.
                printf $2' is file.'\\n > $1/$2                // '$2 is file.' 이라는 문장을 $1 디렉토리 밑에 $2 파일에 printf 하고 줄바꿈(\n: 개행문자)한다.
        else                                                            // 두 번째 매개변수값이 파일이 아니라면,
                echo $2' is not file.'                            // '$2 is not file.' 이라는 문장을 echo 한다.
                touch $1/$2                                       // $1 디렉토리 밑에 $2 파일을 만든다.
                printf $2' file is created.'\\n > $1/$2  // '$2 file is created.' 라는 문장을 $2 파일에 printf 하고 줄바꿈(\\n) 한다.

        fi


라인별 설명은 위 내용을 참조하시면 되겠고,

 

결국 위 구문을 말로 풀어내자면,

 

첫 번째 매개변수값에 해당하는 디렉토리($1)가 존재하면 change directory하고 output으로 생성할 파일($2)이 있는지 확인한 후(없으면 만들고), 조건식의 true 여부에 따라 각각에 해당하는 문장을 echo 및 printf 하겠다는 것입니다.

 

별로 어렵지 않죠?

 

위 구문 중 touch 명령 라인은 굳이 사용하지 않아도 바로 밑 라인의 '>(redirection)' command 에 의해 자동 파일 생성하게 됩니다.

 

echo나 printf 구문 뒤에는 위와 같이 문자열 등이 올 수 있는데, 문자열은 반드시 '(single quotation) 나 "(double quotation)로 wrap 해 주셔야 하며, 위치 매개변수의 경우엔 quotation 바깥에 명시해 주어야만 실제 매개변수값을 전달받을 수 있습니다.(echo $2' is file.')



2) 두 번째 문단 


        ##### Example 2. Arithmetic Comparison Operator
        if [ $3 -gt 1 ]; then
                echo $3' is greater than 1.'
                printf $3' is greater than 1.'\\n >> $1/$2
        elif [ $3 -eq 1 ]; then
                echo $3' is equal to 1.'
                printf $3' is equal to 1.'\\n >> $1/$2
        else
                echo $3' is less than 1.'
                printf $3' is less than 1.'\\n >> $1/$2

        fi


두 번째 문단에서 주의 깊게 살펴 보셔야할 부분은 elif 구문 뒤에 조건식이 들어간다는 것입니다.(지난 글에서는 언급이 없었네요.;;)

 

elif 구문이 else if 구문과 같으므로 당연히 조건식이 들어가야만 하겠죠.(조건식이 없어도 되는 것은 else 뿐입니다.)

 


3) 세 번째 문단 


        ##### Example 3. String Comparison Operator
        if [ $4 == "BMW" -o $5 == "Martiz" ]; then

                if [ $4 == "BMW" ]; then
                        echo $4' is very expensive car.'
                        printf $4' is very expensive car.'\\n >> $1/$2
                fi

                if [ $5 == "Martiz" ]; then
                        echo $5' is twins transformer.'
                        printf $5' is twins transformer.'\\n >> $1/$2
                fi

        else

                echo 'Both '$4' and '$5' are not mine.'
                printf 'Both '$4' and '$5' are not mine.'\\n >> $1/$2

        fi


세 번째 문단은 문자열 비교 예시로써, 앞서 제가 올린 글들을 잘 읽어 보셨다면 역시 별 무리 없이 이해하실 수 있을 것입니다.

 

위 문단에서 한 가지 언급 드리고 싶은 것은 문자열 비교 시에 대소문자를 구분한다는 것입니다.

 

만일 네 번째 위치 매개변수의 값으로 'bmw' 라는 소문자 문자열이 입력되었다면, 위 문단의 두 번째 조건식($4 == "BMW")에서 false 를 리턴하겠죠.

 

이제 이렇게 작성된 스크립트를 실행시키려면, 사용자가 로그인한 바로 그 계정에서 해당 스크립트에 대한 실행 권한이 있어야 합니다.

 

즉, vi 편집기로 위와 같이 작성 완료한 후에 스크립트 실행 전, 다음과 같이 모드를 변경해 주어야 합니다.


# chmod 755 IfTest.sh

# ls -l IfTest.sh

-rwxr-xr-x       1 root        root           1185  Aug    9  16:52   IfTest.sh


권한이나 모드 변경에 대한 것은 이 글을 읽고 있는 분들께서 사전에 알고 계실 것이라 믿고 설명을 생략하도록 하겠습니다.

 

위와 같이 하였다면 이제 다음과 같이 인자를 주고 실행시킨 후, 결과가 잘 나오는지를 확인하면 됩니다.


./IfTest.sh /opt IfTestResult.txt 0 bmw Martiz



이상으로 if문을 포함하는 Shell Script에 대하여 예시를 통해 한 번 알아보았습니다.

posted by 박현명

댓글을 달아 주세요

prev 1 next