Shell 프로그래밍의

Linux/Script | 2004/12/16 22:52 | adioshun
1. Shell 프로그래밍의 개요
(1) 개요
   1) 사용자가 임의로 Shell파일을 만들어 필요시 마다 그 파일을 호출하여 실행한다.
   2) Shell은 보통 언어가 가지고 있는 기본적인 특성을 가지므로 Shell을 이용하여 사용자 환경에
     맞도록 프로그래밍을 할 수 있다.
   3) Shell파일을 이용한 프로그램을 'Shell 프로그램' 또는 'Shell 스크립트'라고 한다.
   4) Shell프로그램의 작성순서
    ㄱ. vi 등 편집기를 이용하여 작성한다.
         예) vi test.sh
    ㄱ. chmod를 이용하여 수행하고자 하는 Shell파일에 실행권한을 부여한다.
         예) chmod 755 test.sh
    ㄷ. 실행시킨다.
         예) [posein@www posein]$ ./test.sh
               => ./를 붙이는 이유는 현재 디렉토리안에 있는 파일을 실행시키라는 의미이다.
                 ./를 사용하지 않으려면 해당 경로를 PATH에 추가하거나 test.sh파일을 PATH에
                 등록되어 있는 디렉토리로 이동시키면 된다.
(2) 쉘스크립트 생성하는 법
   1) vi 편집기등을 이용하여 해당 파일을 생성한다.
      예) vi test.sh
   2) 첫번째 줄은 사용할 쉘을 명시하는 데, bash를 사용할 경우 보통 첫줄에 다음과 같이 표기한다.
      예) #!/bin/bash
   3) 스크립트를 실행 가능한 파일로 만든다.
      예) chmod 755 test.sh
   4) 실행시킨다.
      예) ./test.sh
   5) 참고: 실행권한을 부여하지 않고도 실행을 시킬 수 있는 데, 다음과 같이 3가지 방법이 있다.
    ㄱ. sh 명령이용: sh는 /bin/bash를 직접 사용한다는 의미이다.
      예) sh test.sh
    ㄴ. . 이용
      예) . test.sh: .은 쉘을 사용한다는 의미이다.
    ㄷ. source 이용: source는 bash에서 사용하는 내부명령어계열의 일종으로 쉘을 직접사용한다.
      예) source test.sh
(3) 실행예
   1) 파일 생성
     [posein@www posein]$ vi sample1
     #!/bin/bash
     echo "sample1"
       => vi 편집기를 이용하여 입력한다.
     [posein@www posein]$ ls -l sample1
     -rw-rw-r--    1 posein   posein         15 Jun 25 02:49 sample1
       => 현재 실행권한이 없으므로 실행시킬 수가 없다.
     [posein@www posein]$ chmod 755 sample1
       => 실행권한을 부여하였다.
     [posein@www posein]$ ./sample1
     sample1
       => 현재디렉토리에 경로로 설정이 안되어 있으므로 './'를 붙여서 실행시켜야 한다.
   2) 실행예(실행권한을 부여하지 않은 경우)
    ㄱ. [posein@www posein]$ sh sample1
        sample1
         => 실행권한이 없더라도 앞에 'sh'를 붙여서 실행시킬 수 있다.
    ㄴ. [posein@www posein]$ . sample1
        sample1
   3) 참고 : 일반적인 쉘에서 테스트할 경우 첫번째 줄의 #!/bin/bash는 생략해서 사용가능하나
            제대로 해석하지 못하는 경우가 발생할 수 있으니 꼭 적도록 한다.
--MORE--

2. Shell 프로그래밍 기초
(1) 리다이렉션과 파이프
   1) 다중명령어 사용
    ㄱ. 한 라인에 여러 개의 명령을 입력하면 여러 명령을 수행한다.
    ㄴ. 순차적으로 명령들을 수행할 때 명령들의 구분자는 ';'이다.
    ㄷ. 동시에 명령들을 수행할 때 명령들의 구분자는 '&'이다.
    ㄹ. 사용예
      a. [posein@www posein]$ date; ls -l; whoami
           => 순서대로 실행된다.
      b. [posein@www posein]$ date& ls -l& whoami
           => 동시에 실행된다.
   2) 입출력방향의 재지정
    ㄱ. 표준입출력
       -표준입력(stdin) : 내용입력, 0으로 표기
       -표준출력(stdout) : 내용출력, 1으로 표기
       -표준에러(stderr) : 에러메시지, 2로 표기
    ㄴ. 리다이렉션심볼
       < : 존재하는 파일로 부터 표준입력으로 읽음 (program < input)
       > : 표준 출력으로 파일에 씀 (program > output)
       >> : 존재하는 파일에 표준출력으로 추가함 ( program >> output)
    ㄷ. 입력재지정
      a. 설명: 키보드로부터 명령을 읽는 대신 파일에서 명령을 읽을 때 사용한다.
      b. 입력재지정 기호 : "<"
      c. 사용법
        command < file
      d. 사용예
        [posein@www posein]$ vi red
        ps
        ls
        [posein@www posein]$ sh < red
          PID TTY          TIME CMD
        25289 pts/1    00:00:00 bash
        25581 pts/1    00:00:00 sh
        25582 pts/1    00:00:00 ps
        Desktop  bbb
    ㄹ. 출력재지정
     a. 설명: 명령의 출력을 터미널에 연결하는 대신 파일로 저장할 때 사용한다.
     b. 출력재지정기호 : ">"
     c. 사용법
       command > file
     d. 사용예
       [posein@www posein]$ ls > red2
       [posein@www posein]$ cat red2
       Desktop/
       aaa*
       aaa.sh*
    ㅁ. 출력재지정 추가
     a. 설명: 출력을 파일의 끝에 추가하고자 할 때 사용한다.
     b. 출력재지정기호 : ">>"
     c. 사용법
       command >> file
     d. 사용예
       [posein@www posein]$ ls -l >> red2
    ㅁ. 표준에러 재지정
     a. 설명: 에러메시지를 터미널에 출력하지 않고 파일로 저장할 때 사용한다.
     b. bash인 경우
       command 2 > errfile
        => 표준에러를 errfile에 저장한다.
       (command > file) 2 > errfile
        => 표준출력은 file에, 에러는 errfile에 저장한다.
     c. C shell인 경우
       command >& errfile
        => 표준에러를 errfile에 저장한다.
       (command > file) >& errfile
        => 표준출력은 file에, 에러는 errfile에 저장한다.
     d. 사용예
       1. [posein@www posein]$ ls -z
          ls: invalid option -- z
          Try `ls --help' for more information.
          [posein@www posein]$ ls -z 2>errfile
          [posein@www posein]$ vi errfile
          ls: invalid option -- z
          Try `ls --help' for more information.
       2. [posein@www posein]$ (ls -z > file) 2>errfile2
          [posein@www posein]$ vi file
          [posein@www posein]$ vi errfile2
          ls: invalid option -- z
          Try `ls --help' for more information.
       3. C Shell에서의 표준에러지정
          [posein@www ~]$ ls -z >& errfile
          [posein@www ~]$ vi errfile
          ls: 부적절한 옵션 -- z
          더 많은 정보를 얻으러면 `ls --help'명령을 하십시오.
       4. C Shell에서 표준출력과 표준에러지정
          [posein@www ~]$ ( ls -z > file2) > & errfile3
   3) 파이프
    ㄱ. 파이프를 사용하면 여러 프로세스를 함께 사용할 수 있다.
    ㄴ. 파이프로 연결된 프로세스는 동시에 수행될 수 있으며, 이 프로세스들 사이의 데이터 흐름은
       자동적으로 다시 계획된다.
    ㄷ. 사용법
       program1 | program2 | .....
    ㄹ. 사용예
       1. [posein@www posein]$ ps | sort | more
            PID TTY          TIME CMD
          25289 pts/1    00:00:00 bash
          25649 pts/1    00:00:00 ps
          25650 pts/1    00:00:00 bash
          25651 pts/1    00:00:00 bash
       2. [posein@www posein]$ ps | sort | more > ps.txt
            => 리다이렉션과 함께 사용하여 파일로 저장할 수도 있다.

3. Shell 프로그래밍 문법
(1) 주석
   1) 설명: 주석은 '#'을 이용하며 해당라인 끝까지 처리된다. 이 부분은 쉘실행시 무시되며, 보통
           프로그램에 대한 이해를 돕기위해 사용된다.
   2) 사용예
     #!/bin/sh
     # Auth: posein
     # Work : hello world 를 출력한다.

     echo "hello world"   # 문자열을 출력한다
(2) 변수
   1) 설명: 변수는 모든 프로그래밍언어의 가장 기본이 되는 요소로 어떠한 데이터를 저장하는 공간
           이다. 쉘에서 변수의 타입은 문자열(string)만을 가지면 C언어처럼 변수타입선언이 필요
           없다. 참고로 perl, python, php등도 변수타입선언이 불필요하다.
   2) 사용법
     var=value
      => 변수를 사용할 때는 변수명앞에 $을 붙인다. 또한 변수에 데이터를 저장할 때는 대입연산자인
        '='를 사용하며 대입연산자, 연산자/피연산자 사이에는 공백이 존재해서는 안된다. 또한 변수
        명은 -를 제외한 특수문자와 숫자로 시작해서는 안된다.
   3) 기타변수 대응법
     ㄱ. ${name} : name이라는 변수에 들어있는 값으로 치환한다.(변수명 다음에 다른 문자가 연이
                  어 나올때 유용)
     ㄴ. ${name:=value} : name이 null이면 value로 할당하여 저장하고, 아니면 그냥 기존의 값으로
                         치환한다.(기본값을 지정할 때 유용)
     ㄷ. ${name:+value} : 기존의 name이 null이 아니라면 value를 사용하지만 name에 저장하지는
                         않는다.
     ㄹ. ${name:-value} : 기존에 name값이 있다면 value를 기본값으로 하고  없다면 value반환.
                         name에 value값을 저장하지는 않는다.
     ㅁ. ${name:?value} : 기존에 name값이 있다면 기본값으로 하고 없으면 error를 내면서 value
                         값을 보여준다.
     ㅂ. ${#name} : name의 문자열 길이를 반환
     ㅅ. ${name:offset} : name값에서 offset만큼 삭제한 후에 값을 돌려준다.
     ㅇ. ${name:offset:length} : name값에서 offset만큼 삭제한 후에 length만큼 센 뒤 돌려준다.
   4) 환경변수
    ㄱ. $HOME: 사용자의 홈디렉토리
    ㄴ. $PATH: 명령어 찾기에 사용되는 콜론(:)으로 구분되는 디렉토리 목록
    ㄷ. $LOGNAME: 사용자의 로그인명($USER)
    ㄹ. $MAIL or $MAILPATH: 메일도착을 알고자 할때 사용되는데 둘 중 하나만 지정, $MAIL이 지정
                           되면 메일이 도착할 파일명이 지정되어야 하고 $MAILPATH가 지정되면
                           콜론(:)으로 분리된 메일 파일의 리스트이여야 한다. 메일프로그램이
                           메일을 어디에 놓아야 하는지를 지정하지는 않지만 새로운 메일이 도착
                           하면 Shell이 어디를 찾아야 하는지를 지정한다.
    ㅁ. $MAILCHECK: 메일 파일을 검사하는 초단위 설정
    ㅂ. $SHELL: 로그인 Shell명
    ㅅ. $PS1: Shell이 사용할 첫번째 프롬프트 스트링, 보통은 $
    ㅇ. $PS2: 두번째 프롬프트 스트링, 명령이 완전히 끝나지 않고 Shell이 또 다른 입력행을 요구
             할 경우 사용, 보통 >
    ㅈ. $TERM: 사용자의 터미널형을 포함, vi같은 어떤 명령은 정확한 결과를 나타내기 위해 사용
              중인 터미널의 종류를 나타냄.
    ㅊ. $IFS: 입력필드 구분자, Shell상에서 입력을 읽어들일 때 글자를 구분하기 위한 목적으로
             사용되는 문자 목록, 보통은 스페이스, 탭, 개행문자임.
   5) 아규먼트 변수: 특별한 내장변수로 '위치 매개변수(positional parameter)'라고도 한다. 이
                    변수는 매개변수를 불러올 때 스크립트의 명령행 인자를 담당한다. 위치 매개
                    변수는 그 이름이 1, 2, 3등으로 되어 있고 그 값을 각각 $1, $2, $3등으로
                    표시하고 0은 스크립트 파일명을 뜻한다.
    ㄱ. $0 : 실행된 쉘 스크립트이름
    ㄴ. $1 : 스크립트에 넘겨진 첫번째 아규먼트
    ㄷ. $2 : 스크립트에 넘겨진 두번째 아규먼트
    ㄹ. $# : 스크립트에 넘겨진 아규먼트의 개수
    ㅁ. $$ : 쉘스크립트의 프로세스ID
    ㅂ. $* : 스크립트에 전달된 인자 전체를 하나의 변수에 저장하며 IFS환경변수의 첫번째 문자로
            구분
    ㅅ. $@ : $*와 동일(다른점은 IFS환경변수를 사용하지 않음)
    ㅇ. $? : 실행한 뒤의 반환(return)값, 즉 참이면 0, 거짓이면 1이 반환됨
    ㅈ. $- : 현재 Shell이 호출될 때 사용한 옵션들
   6) 사용예
    ㄱ. [posein@www posein]$ vi test.sh
        #!/bin/sh                         // 리눅스 bash에서는 sh가 bash로 심볼릭링크되어 있음
        # 변수에 값을 할당한다.
        a="hello world"
        # 이제 a라는 변수에 등록된 값을 화면에 출력한다.
        echo "a is : $a"
         => 실행파일로 만들어서 실행시키면 'a is : hello world'가 출력된다.
    ㄴ. [posein@www posein]$ vi test2.sh
        #!/bin/bash
        num=2
        echo "this is the $numnd"
          => 원하는 값이 "this is the 2nd" 이다. 그러나 위의 예제를 실행시키면 "this is the "
            라는 문자열이 출력된다. 왜냐면 쉘은 "numnd"를 하나의 변수명으로 생각하기 때문이다
            만약 원하는 값을 출력하려면 아래와 같이 바꿔야 한다.
    ㄷ. [posein@www posein]$ vi test3.sh
        #!/bin/bash
        num=2
        echo "this is the ${num}nd"
         => 'this is the 2nd' 라고 출력된다.
    ㄹ. [posein@www posein]$ vi var
        #!/bin/bash
        var=             // pwd와 명령어값을 집어넣고 재실행해 볼 것.
        ${var:=ls}
        echo $var
         => var가 null이므로 값에 ls가 들어가면서 해당 명령이 실행된다.
    ㅁ. [posein@www posein]$ echo $DIR

        [posein@www posein]$ echo ${DIR:-temp}
        temp
        [posein@www posein]$ echo $DIR

    ㅂ. [posein@www posein]$ DIR=tmp
        [posein@www posein]$ echo ${DIR:+temp}
        temp
        [posein@www posein]$ echo $DIR
        tmp
    ㅅ. [posein@linux67 posein]$ string1=linux
        [posein@linux67 posein]$ string2=window
        [posein@linux67 posein]$ test $string1 = $string2
        [posein@linux67 posein]$ echo $?
        1
         => $?은 값이 참이면 0, 거짓이면 1을 출력한다.
    ㅇ. [posein@www posein]$ vi test4.sh
         #!/bin/bash
         echo "This script file $0"
         echo "Argument Count is $#"
         echo "Process ID is $$"
         echo "Argument List \$* : $*"
         echo "Argument List \$@ : $@"
         echo "Argument 1: $1"
         echo "Argument 2: $2"
         echo "Argument 3: $3"
         [posein@www posein]$ ./test4.sh a b c
         This script file ./test4.sh
         Argument Count is 3
         Process ID is 31779
         Argument List $* : a b c
         Argument List $@ : a b c
         Argument 1: a
         Argument 2: b
         Argument 3: c
    ㅈ. $@와 $*의 차이점
       [posein@www posein]$ vi ii1
       #!/bin/bash
       IFS=,
       echo "$@"
       [posein@www posein]$ vi ii2
       #!/bin/bash
       IFS=,
       echo "$*"
       [posein@www posein]$ ./ii1 a b c
       a b c
       [posein@www posein]$ ./ii2 a b c
       a,b,c
        => $*는 IFS를 사용하고 $@는 IFS를 사용하지 않는다.
    ㅊ. [posein@www posein]$ count=Ilovebash
        [posein@www posein]$ echo ${count:5}
        bash
        [posein@www posein]$ echo ${count:5:2}
        ba
   7) Shell변수의 출력
    ㄱ. set: 현재 정의되어 있는 모든 변수와 그 값을 출력
    ㄴ. env: export된 변수의 값만 출력
    ㄷ. export
      a. 설명: 특정변수의 범위를 환경 데이터 공간으로 전송하여 자식프로세스에서도 그 특정변수
              를 사용 가능하게 함.
      b. 특징
        - Shell프로그램이 호출될 때 export를 사용한 모든 변수에 대한 복사가 만들어져 호출된
          프로그램으로 전달되게 하여 변수의 범위를 확대시킨다.
        - 인자가 없는 export명령은 export된 변수의 리스트를 얻을 수 있다.
        - 서브 Shell에서 수정된 환경변수값은 부모 Shell에 영향을 주지 못한다.
        - 서브 Shell에서 변수를 export하면 export된 변수는 그 다음 서브 Shell에 영향을 준다.
    ㄹ. 예제
          [posein@www posein]$ vi main
          echo shell programming
          name=test
          city=seoul
          echo name is $name
          echo city is $city
          export name
          ./sub
          echo stop main
          [posein@www posein]$ vi sub
          echo start sub
          echo name is $name
          echo city is $city
          echo stop sub
          [posein@www posein]$ ./main
          shell programming
          name is test
          city is seoul
          start sub
          name is test
          city is
          stop sub
          stop main
   8) 정의된 변수의 제거
    ㄱ. unset 변수명
       => 변수의 값을 널(Null)로 만드는 것이 아니라, 존재하지 않게 한다.
    ㄴ. readonly 변수명
       => 읽기전용 변수로 되어 삭제할 수가 없다.(로그아웃할 때까지 적용된다.)
    ㄷ. 예
       1. [posein@www posein]$ str1=test1
          [posein@www posein]$ echo $str1
          test1
          [posein@www posein]$ unset str1
          [posein@www posein]$ echo $str1
       2. [posein@www posein]$ str2=test2
          [posein@www posein]$ readonly str2
          [posein@www posein]$ echo $str2
          test2
          [posein@www posein]$ str2=test3
          bash: str2: readonly variable
          [posein@www posein]$ echo $str2
          test2
   9) echo문과 escape문자
    ㄱ. 설명: echo문은 라인을 제어하는 명령해석기이며 -e옵션과 같이 \으로 시작하는 escape
             특수문자를 사용할 수 있다.
    ㄴ. 종류
       \b : Backspace
       \c : 새로운 라인의 생성을 억제(bash에서는 안됨)
       \f : Formfeed
       \n : 새로운 라인을 생성
       \r : Carrage Return
       \t : Tab문자
       \\ : Backslash
    ㄷ. 사용예
       [posein@www posein]$ echo "Hi\nHello"
       Hi\nHello
       [posein@www posein]$ echo -e "Hi\nHello"
       Hi
       Hello
   10) 특별구문: expr
    ㄱ. expr은 명령라인에 있는 표현식을 평가한다.
    ㄴ. 수학적인 표현식(+, -, *, /)을 계산하고 표준출력에 결과값을 출력한다.
    ㄷ. 결과값은 역인용부호(`)에 의해 다른 변수에 저장가능하다.
    ㄹ. expr명령은 수식의 연산자 앞 뒤에 반드시 공백이 필요하다.
    ㅁ. 정확한 정수 연산시 사용되고 소수점 계산은 불가능
    ㅂ. 예제
      a. [posein@www posein]$ expr 1 + 2
         3
      b. [posein@www posein]$ int=100
         [posein@www posein]$ expr 100 + $int + 10
         210
      c. [posein@www posein]$ int=0
         [posein@www posein]$ result='expr $int + 5'
         [posein@www posein]$ echo $result
         expr $int + 5
         [posein@www posein]$ result=`expr $int + 5`
         [posein@www posein]$ echo $result
         5
          => 단일 인용부호(' ')를 사용하면 둘러싸인 전체가 변수에 저장되며 역인용부호(` `)를
            사용하면 연산결과가 변수에 저장된다.
      d. [posein@www posein]$ expr 3 * 5
         expr: syntax error
         [posein@www posein]$ expr 3 \* 5
         15
           => *만 사용하면 특수문자로 인식하여 에러가 발생한다. 따라서 *앞에 \를 사용하여 특수
             문자의 의미를 제거하거나 인용부호인 " "나 ' '를 사용해야 한다.
      e. [posein@www posein]$ expr 10 / 3
         3
          => /는 나누어서 몫을 구한다.
      f. [posein@www posein]$ expr 10 % 3
         1
          => %는 나누어서 나머지를 구한다.
   11) 변수타입지정: declare 와 typeset
    ㄱ. 설명: 이 두 명령은 내장명령으로 동의어이다. 역할은 변수의 특성을 제한한다. declare
             명령어는 bash 버전 2이후부터 가능하고 typeset명령은 ksh스크립트에서도 가능하다.
             declare명령을 아무 옵션없이 실행하면 모든 변수값을 출력한다.
    ㄴ. 사용법
       declare [option] [변수=변수값]
    ㄷ. option
       -r : 읽기전용으로 취급한다. readonly로 선언하는 것과 같다.
       -i : 정수로 취급한다.
       -a : 배열로 취급한다.
       -f : 정의된 함수의 목록을 출력한다.
       -F : 정의된 함수의 이름만을 출력한다.
       -x : export시켜서 외부환경에서도 이 변수를 사용할 수 있게 해준다.
    ㄹ. 사용예
     a. [posein@www posein]$ declare
          => 정의된 변수와 함수 등을 보여준다.
     b. [posein@www posein]$ declare -f
        declare -f popd ()
        {
          DIR_STACK=${DIR_STACK#* };
          cd ${DIR_STACK%% *};
          echo "$PWD"
        }
        declare -f pushd ()
        {
          dirname=$1;
          DIR_STACK="$dirname ${DIR_STACK:-$PWD''}";
          cd ${dirname:?"missing directory name."};
          echo "$DIR_STACK"
        }
          => 정의된 함수명과 함수를 출력한다. -f옵션뒤에 함수명을 명기하면 해당 함수에 대한
            정보만을 출력한다.
     c. [posein@www posein]$ declare -F
        declare -f popd
        declare -f pushd
     d. [posein@www posein]$ val1=3 val2=5
        [posein@www posein]$ result1=val1*val2
        [posein@www posein]$ echo $result1
        val1*val2
        [posein@www posein]$ declare -i val3=3 val4=5
        [posein@www posein]$ declare -i result2
        [posein@www posein]$ result2=val3*val4
        [posein@www posein]$ echo $result2
        15
(3) 인용부호
   1) 설명: 쉘에는 특별한 의미를 가지고 있는 특수문자들이 있는데, 이를 메타문자(meta character
           )라고도 한다. 이러한 특수문자를 문자그대로 사용하고자 할 때 즉, 문자나 단어의 특별
           한 의미를 없앨 때 인용부호를 사용할 수 있다.
   2) 종류
     ㄱ. single quotes(' '): 문자열로 표기(변수명 자체를 문자열로 표기)
     ㄴ. double quotes(" "): 문자열로 표기(변수값을 하나의 인자로 인식, 즉 $, `, \는 문자열에서
                            제외됨)
     ㄷ. backslash(\) : 문자의 특수한 기능을 제거
     ㄹ. back quotes(` `) : 명령어로 인식
   3) 사용예
     ㄱ. [posein@www posein]$ echo 'My Home Directory is $HOME'
         My Home Directory is $HOME
          => $HOME을 그냥 문자열로 취급한다.
     ㄴ. [posein@www posein]$ echo "My Home Directory is $HOME"
         My Home Directory is /home/posein
          => $HOME의 값을 출력한다. (" "는 $, `, \의 특수한 기능을 인정)
     ㄷ. [posein@www posein]$ echo "My Home Directory is \$HOME"
         My Home Directory is $HOME
          => \의 특수한 기능을 제거하여 $를 문자열화 하여 $HOME가 출력된다.
     ㄹ. [posein@www posein]$ echo 'My Home Directory is \$HOME'
         My Home Directory is \$HOME
          => ' '는 모든 특수문자를 무조건 문자열처리하므로 그대로 출력된다.
     ㅁ. [posein@www posein]$ echo "Current Directory is `pwd`"
         Current Directory is /home/posein
          => ` `는 명령어가지고 있는 기능을 인정한다. 역시 " "입장에서 봤을 때 ` `의 특수한
            기능을 인정한다.
     ㅅ. [posein@www posein]$ name=posein
         [posein@www posein]$ echo $name
         posein
          => name의 값인 posein을 출력한다.
         [posein@www posein]$ echo \$name
         $name
          => \는 바로 다음 문자의 특수한 기능을 문자열로 전환시킨다.
         [posein@www posein]$ echo \\$name
         \posein
          => 역시 \는 바로 다음에 나오는 \의 특수한 기능을 없앤다.
(4) 간단한 조건문
   1) 설명: test명령을 기본으로 보통 if문과 같이 사용된다. 보통 test라고 입력하지만 보통 쉘
           스크립트상에서는 test라는 명령어를 생략하고 [ ] 로 한다. 이러한 테스트 조건들은
           '['와 ']'사이에 쓰면되고, '['과 ']'사이에는 반드시 공백문자가 들어가야 한다.
   2) 사용법
     test 표현식
     [ 표현식 ]
   3) 표현식
     ㄱ. 문자열비교
        a. [ string ] : string이 빈 문자열이 아니라면 참
        b. [ string1 = string2 ] : 두 문자열이 같다면 참
        c. [ string1 != string2 ] : 두 문자열이 다르면 참
        d. [ -n string ] : 문자열이 null(빈문자열)이 아니라면 참
        e. [ -z string ] : 문자열이 null(빈문자열)이면 참
     ㄴ. 산술비교
        a. [ expr1 -eq expr2 ] : 두 표현식 값이 같다면 참(Equal)
        b. [ expr1 -ne expr2 ] : 두 표현식 값이 같지 않다면 참(Not Equal)
        c. [ expr1 -gt expr2 ] : expr1 > expr2 이면 참(Greater Then)
        d. [ expr1 -ge expr2 ] : expr1 >= expr2 이면 참(Greater Equal)
        e. [ expr1 -lt expr2 ] : expr1 < expr2 이면 참(Less Then)
        f. [ expr1 -le expr2 ] : expr1 <= expr2이면 참(Less Equal)
        h. [ ! expr ] : expr이 참이면 거짓, 거짓이면 참
        i. [ expr1 -a expr2 ] : expr1 AND expr2의 결과, 즉 둘 다 참이면 참
        j. [ expr1 -o expr2 ] : expr1 OR expr2의 결과, 즉 둘 중 하나만 참이면 참
     ㄷ. 파일조건
        a. [ -b FILE ] : FILE이 블럭디바이스이면 참
        b. [ -c FILE ] : FILE이 문자디바이스이면 참
        c. [ -d FILE ] : FILE이 디렉토리이면 참
        d. [ -e FILE ] : FILE이 존재하면 참
        e. [ -f FILE ] : FILE이 존재하고 정규파일이면 참(호환성 문제로 -e보다 -f가 주로 사용)
        f. [ -g FILE ] : FILE에 SGID가 있으며 참
        g. [ -k FILE ] : FILE에 Sticky bit가 있으면 참
        h. [ -L FILE ] : FILE이 심볼릭링크이면 참
        i. [ -p FILE ] : Named pipe이면 참
        j. [ -r FILE ] : 현재 사용자가 읽을 수 있는 파일이면 참
        k. [ -s FILE ] : 파일이 비어있지 않으면 참
        l. [ -S FILE ] : 소켓디바이스이면 참
        m. [ -t FD ] : FD(File Descriptor)가 열려진 터미널이면 참
        n. [ -u FILE ] : FILE에 SUID가 있으면 참
        o. [ -w FILE ] : 현재사용자가 쓸 수 있는 파일(writable file)이면 참
        p. [ -x FILE ] : 현재사용자가 실행할 수 있는 파일(Excute file)이면 참
        q. [ -O FILE ] : FILE의 소유자가 현재 사용자이면 참
        r. [ -G FILE ] : FILE의 그룹이 현재 사용자의 그룹과 같으면 참
        s. [ FILE1 -nt FILE2 ] : FILE1이 FILE2보다 새로운 파일(최근의 파일)이면 참
        t. [ FILE1 -ot FILE2 ] : FILE1이 FILE2보다 오래된 파일이면 참
        u. [ FILE1 -ef FILE2 ] : FILE1이 FILE2의 하드링크, 즉 I-node값이 같으면 참
   4) 사용예
    ㄱ. [posein@www posein]$ vi test5.sh
        if [ -d data ]
        then
        cd data
        echo "data's File List"
        ls
        fi
         => 현재 디렉토리에 data라는 디렉토리가 존재할 경우 data's File LIst라는 문자열과
            함께 파일의 리스트를 보여준다.
    ㄴ. [posein@www posein]$ vi test6.sh
        [ "$LOGNAME" = "root" ]
        echo $?
        [posein@www posein]$ ./test6.sh
        1
         => 로그인한 사용자가 root가 아니므로 반환값이 1, 즉 거짓이다.
    ㄷ. [posein@www posein]$ vi test7.sh
        [ "$LOGNAME" = "posein" ]
        echo $?
        [posein@www posein]$ ./test7.sh
        0
         => 로그인한 사용자와 일치하므로 반환값이 0, 즉 참이다.
    ㄹ. [posein@linux67 posein]$ test 20 -gt 30
        [posein@linux67 posein]$ echo $?
        1
        [posein@linux67 posein]$ test 20 -lt 30
        [posein@linux67 posein]$ echo $?
        0
(5) 목록
   1) 설명: 여러 명령을 실행할 때 앞의 명령의 결과에 의해서 다음행도 결정되어야 할 경우가 있
           다. 이런 경우에 AND나 OR조건을 사용해서 한번에 처리할 수 있다. 이것은 쉘스크립트
           뿐만아니라 명령행에서도 사용가능하다. if문을 사용하는 것보다 간결하다.
   2) 종류
    ㄱ. &&
      a. 설명: AND를 의미한다. &&는 왼쪽 문장이 참이면 오른문장을 실행한다. 수행도중에 결과
              가 거짓이 되면 그 이후의 명령은 수행되지 않는다.
      b. 사용법
        문장1 && 문장2 && 문장3 && .....
      c. 사용예
        [ -f "/etc/shadow" ] && echo "This computer uses shadow passwords"
          => 왼쪽문장이 참이면 오른쪽 문장을 실행시킨다. 즉 /etc/shadow가 존재하면
            "This computer uses shadow passwords"라는 문자열을 출력한다.
    ㄴ. ||
      a. 설명: OR를 의미한다. 각 문장들이 거짓이 나오는 동안에 계속 실행된다. 즉 참이 나오면
              실행을 멈춘다.
      b. 사용법
        문장1 || 문장2 || 문장3 || ...
      c. 사용예
        [posein@icf04 posein]$ vi mail.sh
        #!/bin/sh
        mailfolder=/var/spool/mail/posein
        [ -r "$mailfolder" ] || { echo "Can not read $mailfolder"; exit 1;}
        echo "$mailfolder has mail from : "
        grep "^From " $mailfolder
         => posein이라는 사용자의 메일파일을 검사하여 파일을 읽을 수 없으면 에러메시지와
           함께 종료하고 그렇지 않으면 grep명령을 이용하여 누구한테 메일이 왔는지를 보여
           주는 스크립트이다.
        [posein@icf04 posein]$ ./mail.sh
        /var/spool/mail/posein has mail from :
        From posein  Wed Jun 26 21:50:15 2002
    ㄷ. &&과 ||의 혼용
      a. 설명: &&와 ||는 혼용이 가능하다.
      b. 사용법
        1. && 문장1 || 문장2
         => 조건이 참이면 문장1을 수행하고 조건이 거짓이면 문장2를 수행한다.
        2. && {
               문장1
               문장2
               문장3
              }
           ||
              {
               문장4
               문장5
               문장6
             }
          => 참이냐 거짓이냐에 따라 여러개의 문장을 수행하고 싶을 때는 { }을 사용한다.
      c. 사용예
       [posein@www posein]$ vi test8.sh
       #!/bin/bash
       [ -f /etc/shadow ] && echo "/etc/shadow is existed" || echo "/etc/shadow is not
        existed"
       [posein@www posein]$ ./test8.sh
       /etc/shadow is existed
        => /etc/shadow파일이 존재하면 "/etc/shadow is existed"라는 문자열이 출력되고 존재
         하지 않으면 "/etc/shadow is not existed"가 출력된다. 참고로 root권한자에서 pwunconv
         명령을 내린뒤에 다시 수행시켜보도록 한다.
(6) 조건문
   1) if
    ㄱ. 설명: 참인지 거짓인지를 판단할 때 사용된다. 참이라면 then부분을 실행하고 그렇지 않으
             면 else부분을 실행한다.
    ㄴ. 사용법
      - 형식1(단일 if문)
        
        if [ 조건 ]
        then
         실행문장
        fi

      - 형식2(if ~ else)

        if [ 조건 ]
        then
          실행문장1
        else
          실행문장2
        fi

      - 형식3(if ~ elif) : elif는 else if의 약자로 이 구문은 여러 개 사용해도 무방하다.

        if [ 조건1 ]
        then
           실행문장1
        elif [ 조건2 ]
        then
           실행문장2
        else
           실행문장3
        fi
    ㄷ. 사용예
      a. [posein@icf04 posein]$ vi test.sh
         #!/bin/sh
         if [ "$SHELL" = "/bin/bash" ]
         then
              echo "your login shell is the bash (bourne again shell)"
         else
              echo "your login shell is not bash but $SHELL"
         fi
         [posein@icf04 posein]$ ./test.sh
         your login shell is the bash (bourne again shell)
      b. [posein@linux67 posein]$ vi tt
         if [ "$1" = "rose" ]
         then
          echo ROSE
         else echo FLOWER
         fi
         [posein@linux67 posein]$ ./tt rose
         ROSE
         [posein@linux67 posein]$ ./tt lily
         FLOWER
          => 첫번째 아규먼트값으로 rose가 오면 ROSE가 출력되고 그 외의 경우에는 FLOWER가
            출력된다.
     c. [posein@linux67 posein]$ vi tt2
        if [ "$1" = "rose" ]
        then
          echo ROSE
        elif [ "$1" = "lily" ]
        then
          echo LILY
        else
          echo FLOWER
        fi
        [posein@linux67 posein]$ ./tt2 rose
        ROSE
        [posein@linux67 posein]$ ./tt2 lily
        LILY
        [posein@linux67 posein]$ ./tt2 tulip
        FLOWER
         => 아규먼트에 rose가 오면 ROSE, lily가 오면 LILY, 그 외의 값이 오면 FLOWER가 출력
           된다.
     d. [posein@linux67 posein]$ vi i1
        #!/bin/bash
        echo "읽어들인 파일의 이름은?";read var
        if [ -f $var ]
         then
          echo file
        else
           if [ -d $var ]
             then
               echo directory
           else
               echo "not found"
           fi
        fi
        [posein@linux67 posein]$ ./i1
        읽어들인 파일의 이름은?
        /etc/shadow
        file
     e. [posein@www posein]$ vi i2
        #!/bin/bash
        if test -z "$1"
        then
            echo usage:i2 filename
            exit 1
        fi
        file_size=`wc -c < $1`
        echo the file size $file_size characters
        if test $file_size -le 5120
        then
            echo the file $1 is a small file
        else
            echo the file $1 is a large file
        fi
        [posein@www posein]$ ./i2 /etc/passwd
        the file size 3875 characters
        the file /etc/passwd is a small file
     f. [posein@www posein]$ vi el1
        #!/bin/bash
        echo "Are you man? (y/n)";read var
        if [ "$var" = "y" ]
        then
            echo "You are man"
        elif [ "$var" = "n" ]
        then
            echo "You are woman"
        else
            echo "enter y or n"
        fi
        [posein@www posein]$ ./el1
        Are you man? (y/n)
        y
        You are man
   2) case문
    ㄱ. 설명: 문자열과 일치하는 정규식부분을 찾아 해당하는 정규식 다음에 있는 명령어를 실행시
             킨다. 아래로 계속 내려가면서 문자열에 해당하는 부분을 찾고 보통 맨 마지막에
             나열한 정규식에 해당하지 않는 모든 경우에 해당하는 부분은 *)로 표기한다.
    ㄴ. 사용법
       case 문자열
       in
         정규식1) 명령어1;;
         정규식2) 명령어2;;
       ...
       esac
        => 오른쪽 괄호와 세미콜론은 반드시 사용해야 한다.
    ㄷ. 사용예
     a. [posein@linux67 posein]$ vi tt3
        case $1
        in
          0) echo zero;;
          1) echo one;;
          2) echo two;;
          3) echo three;;
          *) echo greater than four
        esac
        [posein@linux67 posein]$ ./tt3 2
        two
          => 아규먼트와 동일한 정규식을 찾아 해당 명령어를 수행한다.
     b. [posein@www posein]$ vi ca1
        #!/bin/bash
        echo "*********************************************"
        echo "*              보         기                *"
        echo "*********************************************"
        echo "1. who    2. date    3. pwd    4. ls -l     *"
        echo "*********************************************"
        echo "수행하고자 하는 명령어는?(번호를 입력하시오) "
        read number;
        case $number in
          1) who;;
          2) date;;
          3) pwd;;
          4) ls -l;;
          *) echo "없는 번호입니다."
        esac
        [posein@www posein]$ ./ca1
        *********************************************
        *              보         기                *
        *********************************************
        1. who    2. date    3. pwd    4. ls -l     *
        *********************************************
        수행하고자 하는 명령어는?(번호를 입력하시오)
        3
        /home/posein
     c. [posein@www posein]$ vi ca2
        #!/bin/bash
        echo "is it morning? (yes/no)"
        read ans;
        case "$ans" in
             yes | y | Yes | YES)           echo "good morning";;
             no  | n | No | NO)             echo "good afternoon";;
             *) echo "answer not recognize";;
        esac
        [posein@www posein]$ ./ca2
        is it morning? (yes/no)
        n
        good afternoon
   3) select문
    ㄱ. 설명: 이 구문은 다른 쉘에는 없고 콘쉘과 배시쉘에만 존재하는 구문으로 문법이 간결하다.
             구조는 for문과 유사하다.
    ㄴ. 사용법
       select 변수 in 값1, 값2,...
       do
          실행문장
       done
        => in 다음에 나오는 값들이 항목으로 된 메뉴로 생성된다. 이 값들이 생략되면 기본값은
          "$@"가 된다. 형식은 번호를 선택하게 되어 있으며, 사용자에게 번호를 표시해준다.
          "변수"에 선택된 내용을 저장하고 선택된 번호는 내장변수인 REPLY에 저장하고 "실행문장"
           이 실행된다.
    ㄷ.사용예
       [posein@www posein]$ vi sele1
       #!/bin/bash
       echo "What is your favorite OS ?"
       select var in "Linux" "Free BSD" "Windows" "Solaris" "Other"
          do
       
2004/12/16 22:52 2004/12/16 22:52
Trackback address :: http://4ellene.net/tt/trackback/82

Comments List

  1. http://cool.jw.to 2004/12/28 20:27

    <a href="http://coolbias.cafe24.com/zog/" target=_blank ><b>http://cool.jw.to에서 퍼감</b></a><BR/>

  2. 산들바람 2005/07/22 09:52

    <a href=http://blog.naver.com/freshwd target=_blank>http://blog.naver.com/freshwd</a> 에 퍼갑니다~^^

  3. gay hung 2008/05/23 04:42

  4. teeny blowjobs 2008/05/23 07:27

  5. zoophilia storys 2008/05/24 00:43

  6. florida gay marriage rights 2008/05/24 00:47

    嫄몄

Write a comment.

[로그인][오픈아이디란?]