http://wiki.kldp.org/HOWTO//html/Adv-Bash-Scr-HOWTO/index.html


 


http://windwalk.cafe24.com/lectures/lectures_intro.htm 여러가지팁정도....

http://idaemon.com.ne.kr/Linux/Bash/index.html 고급 Bash 스크립팅 하우투

http://doc.kldp.org/HOWTO/html/Bash-Prog-Intro-HOWTO/index.html BASH 프로그래밍 입문

2006/04/05 01:16 2006/04/05 01:16
※  왜 쉘 프로그래밍을 해야 하죠?

 


쉘 스크립트가 어떻게 동작하는지를 이해하는 것은 실력있는 시스템 관리자가 되고 싶어 하는 이들에게는 필수적입니다. 비록 그들이 실제로 스크립트를 작성하지 않는다고 해도 말이죠. 여러분의 리눅스 머신이 부팅될 때를 생각해 봅시다. 부팅이 되면 시스템 설정 정보들을 읽어 들이고 서비스를 구동하기 위해서 /etc/rc.d에 있는 쉘 스크립트를 돌립니다. 이 스크립트들을 자세히 이해하는 것은 시스템의 동작을 분석하기 위해서 매우 중요하기도 하지만 나중에 고칠 필요가 있을지도 모르는 일입니다.


쉘 스크립트를 만드는 것은 배우기가 어렵지 않습니다. 왜냐하면, 몇 개의 쉘용 연산자와 옵션들 [1] 만으로 아주 작게 만들 수 있기 때문입니다. 쉘 문법은 간단하고 명확합니다. 명령어줄 상에서 명령어를 실행시키거나 유틸리티들을 연결해서 실행시키는 것과 거의 비슷하지만 단지 몇 개의 "규칙"만 배우면 됩니다. 거의 대부분의 스크립트가 한 번에 잘 동작하지만 덩치가 큰 스크립트라도 디버깅하기는 쉽습니다.


쉘 스크립트는 아주 복잡한 어플리케이션을 작성하기 전에 "빠르고 간단한" 프로토타입으로 쓰일 수 있습니다. 스크립트가 원래 하려고 하던 기능보다 제한된 기능만 제공하고 속도가 느리더라도 이는 프로젝트 개발의 첫 단계에 있어 아주 유용합니다. 이렇게 하면 실제로 C, C++, 자바, 펄등으로 마지막 코딩에 들어가기에 앞서 전체 동작 상태를 점검해 볼 수 있기 때문에 전체 구조상의 중요한 결함을 발견할 수도 있습니다.


쉘 스크립팅은 복잡한 일들을 작은 단위로 나누어 처리하거나 여러 요소들과 유틸리티를 묶어 처리하는 고전적인 유닉스 철학을 따릅니다. 많은 사람들은, 펄처럼 모든 이에게 모든 것을 제공하면서 모든 기능을 갖고 있는 신세대 언어를 써서 문제를 푸는데 쓸 시간을 그 도구를 익히는데 쓰게 하는 이런 방법보다는 유닉스식을 더 낫다고 생각하고, 적어도 미적으로는 유닉스식이 더 유쾌한 해결법이라고 생각합니다.


쉘 스크립트를 쓰면 안 될 때


 




  • 리소스에 민감한 작업들, 특히 속도가 중요한 요소일 때(정렬, 해쉬 등등)




  • 강력한 산술 연산 작업들, 특히 임의의 정밀도 연산(arbitrary precision)이나 복소수를 써야 할 때(C++이나 포트란을 쓰세요)




  • 플랫폼간 이식성이 필요할 때(C를 쓰세요)




  • 구조적 프로그래밍이 필요한 복잡한 어플리케이션(변수의 타입체크나 함수 프로토타입등이 필요할 때)




  • 업무에 아주 중요하거나 회사의 미래가 걸렸다는 확신이 드는 어플리케이션




  • 보안상 중요해서, 여러분 시스템의 무결성을 보장하기 위해 외부의 침입이나 크래킹, 파괴등을 막아야 할 필요가 있을 때




  • 서로 의존적인 관계에 있는 여러 콤포넌트로 이루어진 프로젝트




  • 과도한 파일 연산이 필요할 때(Bash는 제한적인 직렬적 파일 접근을 하고 , 특히나 불편하고 불충분한 줄단위 접근만 가능)




  • 다차원 배열이 필요할 때




  • 링크드 리스트나 트리같은 데이타 구조가 필요할 때




  • 그래픽이나 GUI를 만들고 변경하는 등의 일이 필요할 때




  • 시스템 하드웨어에 직접 접근해야 할 때




  • 포트나 소켓 I/O가 필요할 때




  • 예전에 쓰던 코드를 사용하는 라이브러리나 인터페이스를 써야 할 필요가 있을 때




  • 독점적이고 소스 공개를 안 하는 어플리케이션을 짜야 할 때(쉘 스크립트는 필연적으로 오픈 소스입니다.)




 


위에서 얘기한 것중 하나라도 맞는 상황이라면 펄이나 Tcl, 파이썬 같은 다른 스크립팅 언어를 쓰거나 C, C++, 자바 같은 고수준 언어를 고려해 보는게 낫습니다. 어쨌든, 어플리케이션의 프로토타입으로 쉘 스크립트를 쓰는 것은 유용한 개발 단계가 될 것입니다.


우리는 Bash를 사용할 것인데 Bash란 "Bourne-Again Shell"의 앞 글자를 딴 것입니다. 이제는 고전인 된 Stephen Bourne의 Bourne Shell에 대한 말장난 같은 겁니다. Bash는 이제 모든 종류의 유닉스에서 쉘 스크립트에 관한 실질적인 표준(de facto)입니다. 이 문서에서 다루고 있는 거의 대부분의 원리들은 Bash가 몇몇 특징을 이어 받은 Korn 쉘 [2] 이나, C 쉘과 그 변형들에도 동일하게 적용됩니다(C 쉘 프로그래밍은 Tom Christiansen이 1993년 10월에 뉴스 그룹 포스팅을 통해 지적했듯이 타고난 문제점을 갖고 있어서 추천하지 않습니다).


다음부터는 쉘 스크립팅에 대한 튜토리얼입니다. 쉘의 특징들을 설명하기 위해서 최대한 예제들을 통해 접근 했습니다. 예제들은 가능한한 모두 테스트해 보았고, 몇몇은 실제로 쓸 만합니다. 독자 여러분은 이 문서의 소스 아카이브에서 실제 예제를 사용할 수가 있습니다(something-or-other.sh). [3] 실행 권한을 주고(chmod u+rx scriptname), 실행을 시킨 다음 어떤 일들이 일어나는지 살펴보십시오. 소스를 구할 수 없다면 여러분이 보고 있는 HTML이나 pdf, text 버전에서 복사-붙여넣기를 하면 됩니다. 몇몇 예제들은 스크립트들은 설명하기 전에 그 특징을 소개할텐데, 이는 여러분들에게 링크를 따라 이곳 저곳을 왔다 갔다 하게 할 지도 모릅니다.


특별한 언급이 없다면 이 문서에서 쓰인 예제들은 모두 저자가 작성한 것입니다.


주석

















[1]

이것들은 내부 명령(builtin)이라고 하는 쉘이 갖고 있는 특징입니다.


[2]

ksh88의 많은 특징들과, 업데이트된 ksh93의 일부분이 Bash로 통합되었습니다.


[3]

관습적으로, 사용자가 작성한 본쉘 호환 스크립트는 보통 .sh 확장자를 갖습니다. 반면에 /etc/rc.d에서 볼 수 있는 시스템 스크립트는 이런 지침을 따르지 않습니다.


2005/12/30 14:18 2005/12/30 14:18
shell과 Shell 프로그래밍

쉘(shell)이란?
쉘의 종류
Standard Input/Output
파이프(pipe), 리다이렉션(Redirection)
Foreground/Background 프로세스
쉘 프로그래밍
-Power On 에서부터 Prompt까지

네이버 링크 : http://blog.naver.com/adioshun/80017461434
2005/12/21 09:32 2005/12/21 09:32
만일 파일들이 제대로 복사가 되었는지 확인하고자 한다면 다음에 있는 스크립트를 사용해도 된다.


#!/bin/sh
cd /
for file in `/bin/ls -1A | egrep -v '^new-disk$|^proc$'`
do
    find $file -xtype f -exec cmp \{\} /new-disk/\{\} \;
done
2005/12/07 09:04 2005/12/07 09:04
1. 날짜별로 디렉토리 만들고 백업

-----------------------------------------------------------------------

#!/usr/bin/perl

# 만든놈 : 정헌학
# 만든날 : 2002.5.7
# 이메일 :
# 설  명 : 자기의 ftp 계정이 있는 서버에 자동접속하여
#          파일을 백업해 준다.
#          백업된 파일 디렉토리는 그 시간에 따른다.

$CMD = "date";
$FTPSERVER = "";
$ID = "hunhakproject";
$PASS = "xxxx";

open(DATE, "$CMD |");
while(<DATE>){
   if(1)
   {
      $_ =~ s/ //g;
   }
   $date = $_;
}    
close(DATE);    

system("ncftpput -u $ID -p $PASS -m -R $FTPSERVER '$date' -R * ");

-----------------------------------------------------------------------
2005/08/01 18:40 2005/08/01 18:40
와니님의 쉘스크립트-----------------

#!/bin/bash

# 초간단 백업스크립트 v0.2
#
# v0.2 - date option %k -> %H
# 유승완 2002/03/20

time=`date +%y%m%d%H%M`
tar cvfz /home/webee/backup/new$time.tar.gz /home/webee/public_html

-----------------------------------------------------------------------

결과물>>

/home/webee/backup 의 내용

total 217320
drwxr-xr-x 2 webee webee 4096 Mar 23 00:02 ./
-rw-rw-r-- 1 webee webee 1087398 Mar 20 10:33 new0203201033.tar.gz
-rw-rw-r-- 1 webee webee 1088182 Mar 20 14:25 new0203201425.tar.gz
-rw-rw-r-- 1 webee webee 758980 Mar 20 16:47 new0203201647.tar.gz
-rw-rw-r-- 1 webee webee 864530 Mar 21 12:31 new0203211231.tar.gz
-rw-rw-r-- 1 webee webee 932607 Mar 23 10:52 new0203231052.tar.gz
-rw-rw-r-- 1 webee webee 1490698 Mar 25 12:20 new0203251220.tar.gz
-rw-rw-r-- 1 webee webee 1619663 Mar 26 13:53 new0203261353.tar.gz
-rw-rw-r-- 1 webee webee 9203357 Mar 27 13:44 new0203271344.tar.gz
-rw-rw-r-- 1 webee webee 9802929 Mar 27 19:10 new0203271909.tar.gz
-rw-rw-r-- 1 webee webee 9872026 Mar 28 16:43 new0203281643.tar.gz
-rw-rw-r-- 1 webee webee 9936915 Apr 1 14:41 new0204011441.tar.gz
-rw-rw-r-- 1 webee webee 9950144 Apr 4 17:19 new0204041718.tar.gz
-rw-rw-r-- 1 webee webee 10285395 Apr 4 22:27 new0204042227.tar.gz
-rw-rw-r-- 1 webee webee 10488162 Apr 10 15:51 new0204101550.tar.gz
-rw-rw-r-- 1 webee webee 10458510 Apr 12 09:28 new0204120928.tar.gz
-rw-rw-r-- 1 webee webee 13900171 Apr 16 10:49 new0204161049.tar.gz
-rw-rw-r-- 1 webee webee 9755464 Apr 18 16:35 new0204181635.tar.gz
-rw-rw-r-- 1 webee webee 13674779 Apr 22 10:42 new0204221042.tar.gz
-rw-rw-r-- 1 webee webee 13682386 Apr 22 14:56 new0204221456.tar.gz
-rw-rw-r-- 1 webee webee 13691321 Apr 22 16:49 new0204221649.tar.gz
-rw-rw-r-- 1 webee webee 13714383 Apr 23 11:38 new0204231137.tar.gz
-rw-rw-r-- 1 webee webee 12275634 Apr 30 13:59 new0204301359.tar.gz
-rw-rw-r-- 1 webee webee 19703506 May 2 13:12 new0205021312.tar.gz
-rw-rw-r-- 1 webee webee 23892797 May 9 15:17 new0205091517.tar.gz

별거 아니구요... 그냥 올려봤습니다. 필요한 분은 쓰세여... ㅋㅋㅋ

디렉토리 통채로 tar압축시켜서리 일정디렉토리에 저장하는 허접스크립이네영... 으헐~

tar cvfz [압축파일저장경로]/[압출파일명] [압축하고자하는 디렉토리 path] <- 압축파일맹글기


박봉기님 쉘 스크립트------------
#!/bin/bash
DATE=$(date +%Y_%m_%d_%H_%M)

tar cvzfp /raid/BACKUP/local/DB_dat_bak_$DATE.tgz --directory /usr/local/mysql/data ./DB ./mysql
tar cvzfp /raid/BACKUP/local/htdocs_bak_$DATE.tgz --directory /usr/local/apache ./htdocs ./cgi-bin

cd /raid/BACKUP/local
/usr/local/mysql/bin/mysqldump -uroot -pxxx DB > DB_$DATE.sql
tar cvzfp DB_sql_bak_$DATE.tgz *.sql
rm -rf *.sql
------------------------------------

-rw-r--r-- 1 root root 17631241 5월 6 02:18 htdocs_bak_2002_05_06_02_02.tgz
-rw-r--r-- 1 root root 18154158 5월 7 02:18 htdocs_bak_2002_05_07_02_02.tgz
-rw-r--r-- 1 root root 17786447 5월 8 02:19 htdocs_bak_2002_05_08_02_02.tgz
-rw-r--r-- 1 root root 17850240 5월 8 11:21 htdocs_bak_2002_05_08_11_19.tgz
-rw-r--r-- 1 root root 18018957 5월 9 02:03 htdocs_bak_2002_05_09_02_02.tgz

-rw-r--r-- 1 root root 42875686 5월 6 02:19 DB_sql_bak_2002_05_06_02_02.tgz
-rw-r--r-- 1 root root 9719430 5월 7 02:18 DB_sql_bak_2002_05_07_02_02.tgz
-rw-r--r-- 1 root root 42930931 5월 8 02:20 DB_sql_bak_2002_05_08_02_02.tgz
-rw-r--r-- 1 root root 42941672 5월 8 11:22 DB_sql_bak_2002_05_08_11_19.tgz
-rw-r--r-- 1 root root 42958879 5월 9 02:05 DB_sql_bak_2002_05_09_02_02.tgz

-rw-r--r-- 1 root root 16844211 5월 2 02:05 DB_dat_bak_2002_05_02_02_04.tgz
-rw-r--r-- 1 root root 17030059 5월 3 02:03 DB_dat_bak_2002_05_03_02_02.tgz
-rw-r--r-- 1 root root 17030055 5월 3 02:05 DB_dat_bak_2002_05_03_02_04.tgz
-rw-r--r-- 1 root root 17148275 5월 4 02:02 DB_dat_bak_2002_05_04_02_02.tgz
-rw-r--r-- 1 root root 17148274 5월 4 02:05 DB_dat_bak_2002_05_04_02_04.tgz
2005/08/01 18:39 2005/08/01 18:39
참고서적 :  초보자용 리눅스 프로그래밍
            ( 대림출판사, 한동훈,이만용역, NEIL MATTHEW, RICHARD STONES 저 )

※ 넷츠고 리눅스 동호회 7월 제 5회 정기 공개강좌 자료
글쓴이 : 위경섭 ( powerhack@netsgo.com )



1. 변수
  . 쉘변수는 처음 사용될때 만들어진다. 즉 미리 선언할 필요가 없다.
  . 쉘변수는 유닉스 명령과 마찬가지로 대소문자에 구별이 있다.
  . 쉘변수는 기본적으로 데이터를 문자열로 저장한다. 수치를 대입해도 실제 수치
    가 아닌 문자열이 저장된다. 계산이 필요할 경우는 자동으로 수치로 변환하여
    계산후 다시 문자열로저장된다.
  . 쉘변수의 값을 사용할 때는 변수명앞에 "$" 를 붙여서 사용한다.
  . 쉘변수에 값을 대입할때는 "$"를 사용하지 않는다.
  . 쉘변수는 타입이 없다. 즉 아무 값이나 다 넣을 수 있다.

1.1 환경변수
  쉘을 기동하고나면 기본적으로 셋팅되어있는 변수들이다. 유닉스/리눅스에는 많은
  환경변수들이 있고 필요한경우 이 변수들을 마치 일반변수처럼 값을 얻어오거나 셋
  팅할 수 있다. 여기서는 쉘과 직접적인 관련이 있는것만 설명한다.
  
  $0 - 실행된 쉘 스크립트 이름
  $# - 스크립트에 넘겨진 인자의 갯수
  $$ - 쉘 스크립트의 프로세스 ID
  
1.2 인자 변수
  쉘스크립트에 인자를 넘겨줄때 그 인자들에 대한 정보를 가지고 있는 변수들.
  
  $1~ $nnn  : 넘겨진 인자들
  $*        : 스크립트에 전달된 인자들을 모아놓은 문자열. 하나의 변수에 저장되며
              IFS 환경변수의 첫번째 문자로 구분된다.
  $@        : $*과 같다. 다만 구분자가 IFS변수의 영향을 받지 않는다.

1.3 일반변수
  일반변수에 특별한 제약은 없다. 단 대소문자 구분만 정확하게 해주면 된다.

  예제 )

  #!/bin/sh
  echo "This Script Executable File : $0"
  echo "Argument Count : $#"
  echo "Process ID : $$"
  echo "Argument List \$* : $*"
  echo "Argument List \$@ : $@"
  echo "Argument 1 : $1"
  echo "Argument 2 : $2"
  echo "Argument 3 : $3"
  echo "Argument 4 : $4"
  
  실행 )
  $chmod 755 test1
  $./test1 a1 a2 a3 a4
  This Script Executable File : ./test1
  Argument Count : 4
  Process ID : 905
  Argument List $* : a1 a2 a3 a4
  Argument List $@ : a1 a2 a3 a4
  Argument 1 : a1
  Argument 2 : a2
  Argument 3 : a3
  Argument 4 : a4

1.4 연산
  변수의 산술연산은 생각하는것 처럼 쉽지않다. 위에서 언급했듯이 변수에는 모든것
  이 문자열로 저장되기 때문에 연산이 불가능하다. 연산을 위해서는 좀 복잡한 절차
  를 거쳐야 한다.

  변수 = $((산술식))

  이것이 가장 단순한 연산 규칙이다. 산술식내에는 변수( $1, $a 와 같은 ) 도 들어
  갈 수 있다. 산술식 내에 숫자가 아닌 문자열, 또는 문자열이 담겨있는 변수가 들어
  가면 그것들은 계산에서 제외된다.
  (정확히 말하면 0 으로 간주되어 연산이 이루어 지지 않는다.)

1.5 매개변수 확장
  매개변수 확장이란 변수의 값을 문자열등으로 대체하는 것을 말한다. 단순한 대체뿐
  아니라 변수내의 문자열을 조작하여 원하는 문자열만을 추출할 수도 있다.

  형식
  ${parm:-default} : parm이 존재하지 않으면 default로 대체된다.


  ${#parm}          : parm의 길이를 참조한다.(가져온다)


  ${parm%word}      : 끝에서부터 word와 일치하는 parm의 최소부분(첫번째 일치) 을
                                      제거하고 나머지를 반환한다.

  ${parm%%word}     : 끝에서부터 word와 일치하는 parm의 최대부분(마지막 일치) 을
                                        제거하고 나머지를 반환한다.


  ${parm#word}      : 처음부터 word와 맞는 parm의 최소부분(첫번째 일치)을 제거하
                                    고 나머지 부분을 반환한다.
  ${parm##word}     : 처음부터 word와 맞는 parm의 최대부분(마지막 일치)을 제거하
                                      고 나머지를 반환한다.
  
  * word에는 와일드 카드를 사용할 수 있다.
  
  예를 보자.
    
  1 #!/bin/sh
  2
  3 p="/usr/X11R6/bin/startx"
  4
  5 unset p
  6 a=${p:-"Variable p Not found"}
  7 echo $a
  8
  9 p="/usr/X11R6/bin/startx"
  10 a=${p:-"Variable parm Not found"}
  11 echo $a
  12
  13 a=${#p}
  14 echo $a
  15
  16 a=${p%/*}
  17 echo $a
  18
  19 a=${p%%/*}
  20 echo $a
  21
  22 a=${p#*/}
  23 echo $a
  24
  25 a=${p##*/}
  26 echo $a
  27                  
  
  위 스크립트의 결과는 다음과 같다.
  ---------------------------------
  Variable p Not found
  /usr/X11R6/bin/startx
  21
  /usr/X11R6/bin

  usr/X11R6/bin/startx
  startx            
  ----------------------------------
   6행 : 변수 p 가 제거 되었으므로 "Variable p Not found" 가 a에 들어간다.
  10행 : 변수 p 가 있으므로 그대로 a에 들어간다.
  13행 : a에는 변수 p의 길이가 들어간다.
  16행 : p 에서 가장 오른쪽의 "/"부터 끝까지 지우고 나머지를 a에 넣는다.
  19행 : p 에서 가장 왼쪽의 "/" 부터 끝까지 지우고 나머지를 a에 넣는다.
         (아무것도 없다)
  22행 : p 의 처음부터 가장왼쪽의 "/" 까지 지우고 나머지를 a에 넣는다.
  25행 : p 의 처음부터 가장 오른쪽의 "/"까지 지우고 나머지를 a에 넣는다.
  
2. 조건 판단
  쉘 스크립트에서 조건판단은 if 와 파일 유형을 점검하고 값을 비교하는 test 명령을

  혼합하여 사용한다.

  일반적인 예는 다음과 같다.

  if test -f test1
  then
   ...
  fi

  -f 는 주어진 인자가 일반파일 일때 참이된다.
  
  
  test 명령은  [] 로 대체될 수 있다.

  if [ -f test1 ]
  then
   ...
  fi

  -----------------------------

  if [ -f test1 ]; then
   ...
  fi

  2.1 test 명령

  test 명령의 조건은 다음과 같이 세 부류로 나누어진다.

  문자열비교
    [ string ]             : string이 빈 문자열이 아니라면 참
    [ string1 = string2 ]  : 두 문자열이 같다면 참
    [ string1 != string2 ] : 두 문자열이 다르면 참
    [ -n string ]          : 문자열이 null(빈 문자열) 이 아니라면 참
    [ -z string ]          : 문자열이 null(빈 문자열) 이라면 참
  
  산술비교
    [ expr1 -eq expr2 ] : 두 표현식 값이 같다면 참 ( EQual )
    [ expr1 -ne expr2 ] : 두 표현식 갑이 같지 않다면 참 ( Not Equal )
    [ expr1 -gt expr2 ] : expr1 > expr2 이면 참 ( Greater Then )
    [ expr1 -ge expr2 ] : expr1 >= expr2 이면 참 ( Greater Equal )
    [ expr1 -lt expr2 ] : expr1 < expr2 이면 참 ( Less Then )
    [ expr1 -le expr2 ] : expr1 <= expr2 이면 참 ( Less Equal )
    [ ! expr ]          : expr 이 참이면 거짓, 거짓이면 참
    [ expr1 -a expr2 ]  : expr1 AND expr2 의 결과 ( 둘다 참이면 참 )
    [ expr1 -o expr2 ]  : expr1 OR expr2 의 결과 ( 둘중 하나만 참이면 참 )
  
  파일조건

    [ -b FILE ]           : FILE 이 블럭 디바이스 이면 참
    [ -c FILE ]           : FILE 이 문자 디바이스 이면 참.
    [ -d FILE ]           : FILE 이 디렉토리이면 참
    [ -e FILE ]           : FILE 이 존재하면 참
    [ -f FILE ]           : FILE 이 존재하고 정규파일이면 참
    [ -g FILE ]           : FILE 이 set-group-id 파일이면 참
    [ -h FILE ]           : FILE 이 심볼릭 링크이면 참
    [ -L FILE ]           : FILE 이 심볼릭 링크이면 참
    [ -k FILE ]           : FILE 이 Sticky bit 가 셋팅되어 있으면 참
    [ -p FILE ]           : True if file is a named pipe.
    [ -r FILE ]           : 현재 사용자가 읽을 수 있는 파일이면 참
    [ -s FILE ]           : 파일이 비어있지 않으면 참
    [ -S FILE ]           : 소켓 디바이스이면 참
    [ -t FD   ]           : FD 가 열려진 터미널이면 참
    [ -u FILE ]           : FILE 이 set-user-id 파일이면 참
    [ -w FILE ]           : 현재 사용자가 쓸 수 있는 파일(writable file) 이면 참
    [ -x FILE ]           : 현재사용자가 실행할 수 있는 파일(Executable file) 이면 참
    [ -O FILE ]           : FILE 의 소유자가 현재 사용자이면 참
    [ -G FILE ]           : FILE 의 그룹이 현재 사용자의 그룹과 같으면 참
    [ FILE1 -nt FILE2 ]   : FILE1이 FILE2 보다 새로운 파일이면 ( 최근파일이면 ) 참
    [ FILE1 -ot FILE2 ]   : FILE1이 FILE2 보다 오래된 파일이면 참
    [ FILE1 -ef FILE2 ]   : FILE1 이 FILE2의 하드링크 파일이면 참
  
  2.2 if 구문
    if 문은 조건을 판단하여 주어진 문장을 수행한다.
  
    1. 형식 1  ( 단일 if 문 )
    형식 :
      if [ 조건 ]
      then
        문장1
        문장2
      fi
    
    2. 형식 2  ( if~else 문 )
    형식 :
      if [ 조건 ]
      then
        문장3

      else
        문장4
      fi
    
    3. 형식 3  ( if~elif 문 )
    형식 :
      if [ 조건 ]
      then
        문장1
        문장2
      elif
        문장3
        문장4
      else
        문장5
        문장6
      fi
    
  2.3 case 구문
  ※ 패턴에는 * 문자, 즉 와일드카드를 사용할 수 있다.
  형식 :
      case 변수 in
        패턴 [ | 패턴 ] ... ) 문장 ;;
        패턴 [ | 패턴 ] ... ) 문장 ;;
        ....
        * ) 문장 ;;
      easc
  
  2.4 목록
    여려명령을 실행할때 앞의 명령의 결과에 의해서 다음행동이 결정되어야 할 경우
    가 있다. 이런경우에 AND나 OR조건을 사용해서 한번에 처리할 수 있다. 이것은 쉘
    스크립트 뿐 아니라 명령행에서도 사용 가능하다. 물론 if 문을 이용해서 반환값
    을 검사하여 처리할 수 있지만 문장이 길어지고 복잡해진다.
  
    AND 목록

        statment1 && statment2 && statmentN && .....

        위의 명령들은 각 명령이 거짓이 될 때 까지 명령을 수행해 나간다. 수행도중
        결과가 거짓이 되면 그이후의 명령은 수행되지 않는다.

    OR  목록

        statment1 || statment2 || statmentN || .....

        위의 명령들은 각 명령이 거짓이 나오는 동안 계속된다. 즉 참이 나오면 실행
        을 멈춘다.

    AND와 OR목록은 혼용이 가능하다.

        [ 조건 ] && 문장1 || 문장2

        위의 예는 조건이 참이면 문장1을 수행하고 거짓이면 문장2를 수행한다.

        또한 위의 문장1이나 문장2에서 여러개의 문장을 수행 하고 싶을 때는 {}를
        사용하면 된다.

        [조건] && {
                    문장1
                    문장2
                    문장3
                          } || {
                                 문장4
                                 문장5
                                 문장6
                               }

3. 제어문
  3.1 for
  for 문은 지정된 범위안에서 루프를 수행한다. 범위는 어떤 집합도 가능하다.
  형식 :
         for 변수 in 값1, 값2, ...
         do
             문장
         done

  매 루프를 돌때마다 변수의 값은 in 이후의 값으로 대체된다.
  예)
      for str in "test1", "test2", "test3", "test4"
      do
         echo @str
      done

  출력 )

      test1
      test2
      test3
      test4
  
  값에는 와일드 카드 확장을 사용할 수 있다.

    for file in $(ls -a | grep "^.")
    do
      echo "$file is Hidden File"
    done

  위 예의 출력 결과는 현재디렉토리에서 처음이 "." 으로시작하는 파일(히든파일) 만
  을 출력한다.

  for file in $(ls chap[345].txt); do
      echo "--- $file ---" >> Books.txt
      cat $file >> Books.txt
  done

  위의예는 chap3.txt, chap4.txt, chap5.txt 파일을 Books.txt 라는 파일에 붙여 넣
  는다.

  다음의 예를 보고 결과를 예측해보자

  echo "\$* output"

  for fvar in $*
  do
    echo $fvar
  done

  echo "\$@ output"
  for fvar in $@
  do
    echo $fvar
  done
    
  3.2 while
    for 명령의 경우는 횟수를 지정해서 루프를 수행하는데는 문제가 있다.
    while 문은 실행횟수가 지정되지 않았을때 편리하다.
  
    형식 :
           while 조건문
           do
                문장
           done
  
    예제를 보자. 패스워드를 입력받고 맞는지 확인하는 프로그램이다.

    echo "Enter Password : "
    read password1

    echo "Retype Password : "
    read password2

    while [ "$password1" != "$password2" ]
    do
         echo "Password miss match Try again "

         echo "Retype Password : "
         read password2
    done

    echo "OK Password Match complete"
  


    어떻게 동작하는가 ?
    
  3.3 until
    until은 while문과 동일한 효과를 내지만 조건이 반대이다. 즉, while문은 조건이
    참 일동안 루프를 수행하지만 until은 조건이 거짓일 동안 루프를 수행한다.
  
    형식 :
      until 조건문
      do
       문장
      done
  
    다음 예를 보자. 이 예는 지정한 유저가 로그인 하면 알려준다.
  
    #!/bin/sh
  
    until who | grep "$1" > /dev/null
    do
        sleep 10
    done
  
    echo "User $1 just logged in ^_^"
  
3.4 select
    select 문은 원하는 리스트를 출력하고 그중 선택된것을 돌려주는 구문이다. 주의
    할점은 select의 루프내에서는 자동적으로 루프를 벗어날 수 없다. 반드시 break
    문을 사용해서 루프를 벗어나야 한다.
  
    예) 간단한 퀴즈 ^_^

      #!/bin/sh
    
      echo "다음중 스크립트언어 프로그래밍에 속하는 것은 ?"
      select var in "쉘 프로그래밍" "C 프로그래밍" "자바 프로그래밍" "Exit"
      do
          if [ "$var" = "쉘 프로그래밍" ]
          then
                  echo "정답입니다."
                  exit 0
          elif [ "$var" = "Exit" ]
          then
                  echo "종료합니다."
                  exit 1
          else
                  echo "$var 을 선택하셨습니다. 오답입니다."
                  echo "다음중 스크립트언어 프로그래밍에 속하는 것은 ?"
          fi
      done

4. 함수
  쉘 스크립트 내부에 또는 다른 스크립트파일에 함수를 정의해 놓고 사용할 수 있다.
  함수를 사용하면 코드를 최적화 할 수 있고, 코딩이 간결해지며,재사용이 가능하다.
  그러나 다른 스크립트 파일을 호출해서 함수를 실행할 경우, 가능은 하지만 스크립
  트의 실행시간이 길어지고, 함수의 결과를 전달하는 것이 까다롭기 때문에 가급적이
  면 외부파일의 함수는 안쓰는 것이 좋다.

  형식 :
    정의 -
    함수명 ()
    {
     문장
     return 값
    }
  
    사용
  
    함수명 인자1, 인자2, ...
  
  
    함수는 독립적으로 $#, $*, $0 등의 인자변수를 사용한다. 즉 함수내의 $#과 본체
    의 $#은 다를 수 있다는 것이다.
  
    다음의 예를 보자
  
    #!/bin/sh
  
    func()
    {
      echo ------ this is func --------
      echo "This Script Executable File : $0"
      echo "Argument Count : $#"
      echo "Process ID : $$"
      echo "Argument List \$* : $*"
      echo "Argument List \$@ : $@"
      echo "Argument 1 : $1"
      echo "Argument 2 : $2"
      echo "Argument 3 : $3"
    }
  
    echo ------ this is main --------
    echo "This Script Executable File : $0"
    echo "Argument Count : $#"
    echo "Process ID : $$"
    echo "Argument List \$* : $*"
    echo "Argument List \$@ : $@"
    echo "Argument 1 : $1"
    echo "Argument 2 : $2"
    echo "Argument 3 : $3"
    echo "Argument 4 : $4"
    func aa bb cc


    본체와 함수에서 동일한 변수를 보여주지만 값은 틀린다는것을 알 수 있다.
  
    함수에서 값을 반환하기 - 함수에서 반환값은 반드시 정수값만을 반환할 수 있다.
    이 값을 if등으로 조건을 판단해서 사용할 수 있다. 반환값중 0은 참으로 나머지
    숫자는 거짓으로 판별된다.
  
5. 명령어
  쉘에서 쓸 수 있는 명령어는 두가지로 나누어진다. 명프롬프트 상에서 실행 시킬 수
  있는 외부 명령어와 쉘 내부 명령이다. 내부명령은 보통 쉘 내부나 쉘 구문상에서
  쓰인다. 외부명령은 쉘에 관계없이 사용이 가능하다.

  break
    제어문이나 조건문의 루프를 빠져나갈때 사용한다.
    예)
     while [ $a -eq 10 ]
     do
      if [ $a -eq 5 ]; then
       break
      fi
     done

  :명령
    의미없는 명령. 논리값 true를 대신해 쓰기도 한다.
  
  continue
    제어문이나 조건문의 처음으로 돌아가서 다시수행한다.
    예)
     while [ $a -eq 10 ]
     do
         if [ $a -eq 5 ]; then
               continue
            fi
     done
  
  . 명령
    . 명령을 사용하면 현재 쉘에서 명령을 실행시킨다 그러므로 실행된 명령의 결과
    를 본 프로그램에서 사용할 수 있다.
  
    예를 들면 A 라는 스크립트에서 B라는 스크립트를 그냥 실행할 경우 B에서의 변화
    (환경변수 등)는 A에게 아무런 영향도 미치지 않는다. 그러나 . 명령을 사용해서
    실행하면 B에서의 변화가 A에도 영향을 미친다.
  
  echo
    문장을 출력한다. 자동으로 개행문자가 삽입된다. ( 다음줄로 넘어간다 )

  eval
    인자의 실제 값을 구하는데 사용한다.
  
    foo=10
    x=foo
    y='$'$x
    echo $y
  
    이 예를 실행해 보면 $foo가 출력된다
  
    foo=10
    x=foo
    eval y='$'$x
    echo $y
  
    이 예에서는 $foo의 값 즉 10 이 출력된다. eval명령은 원하는 문자열들을 조합해
    서 변수를 액세스 할 수 있다.

  exec
    현재쉘을 다른 프로그램으로 대체한다.
  
    예 ) exec csh

  exit n
    현재 쉘을 종료한다. 종료시 n 값을 리턴한다.

  export
    해당 쉘에서 파생된 자식 프로세스에서 export한 환경변수는 본래 쉘에서 관리한
    다.

  expr
    표현식의 값을 구한다.    ( x=`expr 1 + 2` )
    요즘은 expr보다는 $((계산식)) 구문을 많이 사용한다.

  printf
    C 언어의 printf명령과 흡사하다.
  
    형식 :  printf "Format String" arg1 arg2 arg3 ...
  
  return
    쉘함수에서 값을 반환 할 때 쓰인다.
    0은 성공을 1~125까지는 쉘 에러코드를 나타낸다.

  set
    쉘 내부에서 매개 인자를 설정한다.
    set의 인자로 쓰인 문자열은 공백에 의해 $1 부터 차례대로 대입된다.
  
    예)
  
    #!/bin/sh
    echo $#
    set $(ls)
    echo $#
  
    결과는
  
    0
    22
  
    이다..( 22는 필자의 ls 결과의 갯수이다. ). 첫번째 0는 이 스크립트에 인수가
    없으므로 0이고 set $(ls) 에 의해서 인수의 갯수가 22개로 늘었다.

  shift
    쉘의 인자를 한자리씩 아래로( n -> 1 로 ) 이동시킨다.
  
    예)
    #!/bin/sh
  
    echo $1
    shift
    echo $1
    shift 5
    echo $1
  
    #./myscript 1 2 3 4 5 6 7 8 9 0
    1
    2
    7

trap
    쉘의 실행도중 시그널을 처리하는 시그널 처리기를 만드는 역할을 한다.
  
    형식 : trap command signal
  
    쉘 스크립트는 위에서 아래로 실행되므로 보호하려는 부분 이전에 trap명령을 사
    용해야 한다. trap조건을 기본으로 사용하려면 명령에 - 를 넣으면 된다.
    신호를 무시하려면 '' 빈 문자열을 준다.

  unset
   변수나 함수를 제거한다.

6. 명령실행
  외부명령의 실행 결과를 변수에 집어넣어 변수의 값으로 사용할 수 있다.

  형식 : x = $(명령)

  이렇게 변수에 결과를 넣은 후에는 이 변수를 일반문자열로 생각하고 원하는 가공을
  해서 결과를 얻어낼 수 있다.
  위에서 보았던 매개변수 확장이나 set명령을 이용해서 원하는 부분을 추출해 내면
  그만이다.

7. 쉘 스크립트 내부에서 명령에 입력 전달하기 ( Here Documents )
  이 기능은 쉘 내부에서 명령어에 입력을 전달하는 방법이다. 전달된 입력은 마치 키
  보드에서 눌려진 것 처럼 반응한다.

  형식 :  명령 << 종료문자열
    입력값.....
    종료문자열
  예제 ) 자동으로 메일을 보내는 스크립트

  #!/bin/sh

  mail $1 << myscript
  This is Header
  This is Body
  .

  myscript
2005/07/30 04:13 2005/07/30 04:13


쉘 프로그래밍 문법

 


 


1. 매개변수(파라메타)


쉘 변수에는 세가지 유형이 있으며 이는 매개 변수로 알려져 있다. 그종류는 키워드 매개 변수, 위치 매개변수, 특수 쉘 매개변수 등이다.


1) 키워드 매개 변수


키워드 매개변수명은 알파벳 문자나 _ (밑줄) 문자로 시작 되어야 한다. 그리고 그 다음에는 알파벳이나 밑줄문자의 임의의 숫자가 올 수 있다. 그 값들은 다음과 같이 기록함으로써 키워드 매개변수에 배정된다.


변수=값 변수=값 ...


2) 위치 매개 변수