FREEDOM. FRIENDS. FEATURES. FIRST.
페도라 한국 사용자 모임

쉘 스크립트에서 스트링을 글자처리하는 방법

게시판 질문게시판 쉘 스크립트에서 스트링을 글자처리하는 방법

  • This topic has 11개 답변, 3명 참여, and was last updated 10 years, 10 months 전에 by 딱털서어. This post has been viewed 31 times
  • 만든이
    게시글
  • #13050
    딱털서어
    참가자
    • 게시글87
    • 댓글316
    • 총합403
    • ★★
    @no1linuxer

    네임서버 구축에 관련된 쉘 스크립트를 작성해 놓았는데, 이 스크립트 안에 데몬 띄우는 init 스크립트 내용이 들어갑니다.

    cat > /etc/init.d/named <<EOT
    init 스크립트 내용.....
    EOT

    이렇게요. 그런데 init 스크립트 내용에 $2, $0와 같은 스트링이 들어가는데, 네임서버구축 스크립트를 실행하게 되면 이 부분이 처리될 때 스트링이 문자로 처리되어야 하는데, 해당 변수로 처리되거든요.

    변수처리되지 않고 스트링 자체를 글자로 인식되게 끔 하려면 어떻게 처리해 주어야 하나요?

    좀 더 자세한 이해를 위해서 해당 부분의 스크립트를 첨부합니다.

    ## INIT Scrypt
    cat > /etc/init.d/named <<EOT
    #!/bin/bash
    #
    # named           This shell script takes care of starting and stopping
    #                 named (BIND DNS server).
    #
    # chkconfig: 345 55 45
    # description: named (BIND) is a Domain Name Server (DNS) \
    # that is used to resolve host names to IP addresses.
    # probe: false

    # Comments to support LSB init script conventions
    ### BEGIN INIT INFO
    # Provides: $named
    # Required-Start: $network
    # Required-Stop: $network
    # Should-Start: mysqld postgresql ldap
    # Should-Stop: mysqld postgresql ldap
    # Default-Start:  3 4 5
    # Default-Stop: 0 1 6
    # Short-Description: start and stop BIND
    # Description: named (BIND) is a Domain Name Server (DNS).
    ### END INIT INFO

    # Source function library.
    . /etc/rc.d/init.d/functions

    # Source networking configuration.
    [ -r /etc/sysconfig/network ] && . /etc/sysconfig/network

    RETVAL=0
    prog="named"

    # Check that networking is up.
    [ "${NETWORKING}" = "no" ] && exit 0

    [ -f /etc/sysconfig/named ] && . /etc/sysconfig/named

    [ -f /usr/sbin/named ] || exit 0

    [ -f /var/named/etc/named.conf ] || exit 0

    start() {
            # Start daemons.
            if [ -n "`/sbin/pidof named`" ]; then
                gprintf "$prog: already running"
                echo
                return 1
            fi
            gprintf "Starting %s: " $prog

            # prepare the chroot if needed
            [ -e /var/named/dev/null ] || mknod -m 0666 /var/named/dev/null c 1 3
            [ -e /var/named/dev/random ] || mknod -m 0666 /var/named/dev/random c 1 8
            [ -e /var/named/dev/urandom ] || mknod -m 0666 /var/named/dev/urandom c 1 8

            # better always copy localtime so it respects the system's timezone
            install -m 0644 -o root -g root /etc/localtime /var/named/etc/

            [ -d /var/named/proc ] || mkdir -p /var/named/proc
            if ! egrep -q '^/proc[[:space:]]+'/var/named'/proc' /proc/mounts; then
                mount --bind /proc /var/named/proc -o ro >/dev/null 2>&1
            fi

            daemon named -u named -t /var/named ${OPTIONS}
            RETVAL=$?
            [ $RETVAL -eq 0 ] && touch /var/lock/subsys/named
            echo
            return $RETVAL
    }
    stop() {
            # Stop daemons.
            gprintf "Stopping %s: " $prog
                /usr/sbin/rndc -c /var/named/etc/rndc.conf stop "$1"
            RETVAL=$?
            [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/named || {
                killproc named
                RETVAL=$?
                [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/named
                echo
                return $RETVAL
            }

            if egrep -q '^/proc[[:space:]]+'/var/named'/proc' /proc/mounts; then
                umount /var/named/proc >/dev/null 2>&1
            fi

            success
            echo
            return $RETVAL
    }
    status() {
            /usr/sbin/rndc -c /var/named/etc/rndc.conf status
            return $?
    }
    restart() {
            stop
            # wait a couple of seconds for the named to finish closing down
            sleep 2
            start
    }
    reload() {
            /usr/sbin/rndc -c /var/named/etc/rndc.conf reload "$1" >/dev/null 2>&1 || /usr/bin/killall -HUP named
            return $?
    }

    # See how we were called.
    case "$1" in
            start)
                    start
                    ;;
            stop)
                    stop "$2"
                    ;;
            status)
                    status
                    ;;
            restart)
                    restart
                    ;;
            condrestart)
                    [ -f /var/lock/subsys/named ] && restart
                    ;;
            reload)
                    reload "$2"
                    ;;
            *)
                    gprintf "Usage: %s {start|stop|status|restart|condrestart|reload|probe}\n" $0
                    exit 1
    esac
    EOT

    리눅스를 더 가까이 - No1.Linux

10 답변 글타래를 보이고 있습니다
  • 글쓴이
    답변
    • #14148
      인베인
      참가자
      • 게시글141
      • 댓글379
      • 총합520
      • ★★
      @leemgs

      초기의 본쉘프로그래밍하시는 분이 자주 실수하는 것중의 하나가,
      prog="named" 변수 선언시에 스페이스  누르는거죠?? 예전 얘기이지만, 저는 자주 그랬다는..ㅡ.ㅜ;;

      * 오픈소스는 Open Innovationa & 윈윈전략을 도모할 지언정 절대 공짜(무료)임을 뜻하지 않는다.치

    • #14149
      딱털서어
      참가자
      참가자
      • 게시글87
      • 댓글316
      • 총합403
      • ★★
      @no1linuxer

      저 내용에서 $0이 문자로 그대로 들어가게 끔 하려면 어캐 해야 합니까?

      리눅스를 더 가까이 - No1.Linux

    • #14150
      ELem
      참가자
      • 게시글67
      • 댓글672
      • 총합739
      • ★★
      @Bardisch

      쉘스크립트는 어쩔지 잘 모르겠지만...
      보통 "$0" 이런식으로 하면 문자열로 처리되지 않나요?
      쉘 스크립트는 해보려다가 말아서[..]

    • #14151
      인베인
      참가자
      • 게시글141
      • 댓글379
      • 총합520
      • ★★
      @leemgs

      제 경우에는 printf "Usage: %s {start|stop|status|restart|condrestart|reload|probe}\n" $0
      이런 형식으로 출력하였었습니다. 이렇게 하시면 될텐데??

      * 오픈소스는 Open Innovationa & 윈윈전략을 도모할 지언정 절대 공짜(무료)임을 뜻하지 않는다.치

    • #14152
      딱털서어
      참가자
      참가자
      • 게시글87
      • 댓글316
      • 총합403
      • ★★
      @no1linuxer

      알려 주신 그대로 실행한 결과입니다.

      [root@localhost rpm]# cat > test.sh
      #!/bin/sh

      cat > testscpt.sh <<EOT
      printf "Usage: %s {start|stop|status|restart|condrestart|reload|probe}\n" $0
      EOT
      [root@localhost rpm]# chmod 755 test.sh
      [root@localhost rpm]# ./test.sh
      [root@localhost rpm]# cat testscpt.sh
      printf "Usage: %s {start|stop|status|restart|condrestart|reload|probe}\n" ./test.sh

      마찬가지로 $0는 문자처리되지 않고 변수값으로 처리됨을 볼 수 있습니다. 실행한 스크립트명 test.sh이므로 $0는 test.sh가 되지만, 의도하는 바는 스크립트 파일을 따로 만드는 것이라 $0는 스트링이 아니라 문자 그 자체이어야 하거든요.

      리눅스를 더 가까이 - No1.Linux

    • #14153
      딱털서어
      참가자
      참가자
      • 게시글87
      • 댓글316
      • 총합403
      • ★★
      @no1linuxer

      혹시 변수를 초기화시키는 것에 대해서 알고 계시는지요?

      unset 명령으로 변수를 초기화시킬 수 있다고 하는데, 상기 내용에서는 어떻게 이 명령으로 초기화시킬지 모르겠군요. 스크립트내의 스크립트 문장은 원 스크립트의 변수 적용이 되지 않아야 하는 건데, EOT문에 있는 내용들을 모두 문자로만 기록되도록 하면 되는데....어딜 봐도 이런 내용이 없으니 갑갑하네요.

      리눅스를 더 가까이 - No1.Linux

    • #14154
      인베인
      참가자
      • 게시글141
      • 댓글379
      • 총합520
      • ★★
      @leemgs

      그렇군요. 스트링 자체를 글자로 인식하게 하여 "스크립트 명령 코드" 파일을 만들고자 한다면,
      오히려 printf명령이 아닌 echo명령으로 해보세요. 이해를 돕기 위해 간단히 작성해보았습니다.

      [invain@localhost opt]$
      [invain@localhost opt]$ vi ./testscpt.sh
      #!/bin/sh
      # simple script to make commands automatically
      # by invain
      cat << EOT >testscpt_result.sh
      echo "Usage: $0 {start|stop|status|restart|condrestart|reload|probe}\n"
      EOT
      [invain@localhost opt]$
      [invain@localhost opt]$ ./testscpt.sh
      [invain@localhost opt]$ cat ./testscpt_result.sh
      echo "Usage: ./testscpt.sh {start|stop|status|restart|condrestart|reload|probe}\n"
      [invain@localhost opt]$

      * 오픈소스는 Open Innovationa & 윈윈전략을 도모할 지언정 절대 공짜(무료)임을 뜻하지 않는다.치

    • #14155
      딱털서어
      참가자
      참가자
      • 게시글87
      • 댓글316
      • 총합403
      • ★★
      @no1linuxer

      인베인님

      [invain@localhost opt]$ cat ./testscpt_result.sh
      echo "Usage: ./testscpt.sh {start|stop|status|restart|condrestart|reload|probe}\n"
      [invain@localhost opt]$

      testscpt_result.sh 파일 내용에서 .testscpt.sh로 되어서는 안되는거든요. .testscpt.sh가 원래의 $0이 되어야 하는게 제 목적이거든요. testscpt.sh 파일에선 변수처리가 이뤄지더라도 testscpt_result.sh 파일은 testscpt.sh와는 무관하기 때문에 testscpt.sh에 있는 변수가 넘어가선 안되기 때문입니다.

      echo "Usage: ./testscpt.sh {start|stop|status|restart|condrestart|reload|probe}\n"

      => echo "Usage: $0 {start|stop|status|restart|condrestart|reload|probe}\n"

      리눅스를 더 가까이 - No1.Linux

    • #14156
      딱털서어
      참가자
      참가자
      • 게시글87
      • 댓글316
      • 총합403
      • ★★
      @no1linuxer

      해결했슴다....

      $0 앞에 \를 붙여주면 변수처리가 이뤄지지 않는군요...

      이걸 몰라서 이제까지 헤매였습니다.

      $ cat test.sh

      #!/bin/sh
      # simple script to make commands automatically
      cat << EOT >testscpt_result.sh
      echo "Usage: \$0 {start|stop|status|restart|condrestart|reload|probe}\n"
      EOT

      $ ./test.sh

      $ cat testscpt_result.sh
      echo "Usage: $0 {start|stop|status|restart|condrestart|reload|probe}\n"

      리눅스를 더 가까이 - No1.Linux

    • #14157
      인베인
      참가자
      • 게시글141
      • 댓글379
      • 총합520
      • ★★
      @leemgs

      아 아깝다.. 딱털서어님이 하시고자 하는 것을 제가 잘못이해했었군요. 흐흐 저는 사용자가 입력한  명령의 값자체를 넣고자 하시는줄 알았습니다. ㅜㅜ 하여튼 해결되셔서 축하드리옵니다.

      * 오픈소스는 Open Innovationa & 윈윈전략을 도모할 지언정 절대 공짜(무료)임을 뜻하지 않는다.치

    • #14158
      딱털서어
      참가자
      참가자
      • 게시글87
      • 댓글316
      • 총합403
      • ★★
      @no1linuxer

      제가 의사전달을 잘못한 것 같아 오해하신 것 같습니다.

      암튼 도움을 주시려고 노력하신데 고마울 따름입니다.

      사실 겪고 있는 문제점을 질문자도 제대로 이해하질 못하면 질문이 어려웝긴 하지요,

      리눅스를 더 가까이 - No1.Linux

10 답변 글타래를 보이고 있습니다
  • 답변은 로그인 후 가능합니다.