블로그 이미지
GUCCI

카테고리

전체보기 (111)
여행 (1)
기기 (2)
쇼핑 (0)
게임 (0)
etc. (6)
취업이야기 (0)
업무일지 (5)
리눅스 (38)
쉘스크립트 (5)
임베디드리눅스 (0)
리눅스명령어 (11)
웹프로그래밍 (2)
네트워크 (4)
JAVA (17)
Android (0)
IOS (2)
LUA (8)
C/C++ (1)
Objective C (2)
SERVER (2)
그누보드4 (1)
MSSQL (2)
Programming (1)
자바스크립트 (4)
HTML/CSS (1)
LGNAS (0)
Total
Today
Yesterday

'리눅스/쉘스크립트'에 해당되는 글 5건

  1. 2012.02.14 쉘 내장 명령어 2
  2. 2012.02.09 쉘 프로그래밍 강좌 2
  3. 2012.02.08 쉘스크립트 조건문 7
  4. 2012.02.08 쉘스크립트 1
  5. 2012.02.08 #!/bin/sh 3
 :  아무 것도 수행하지 않고 종료 상태만 0으로 반환한다.
.file 마침표(.)명령어는 파일을 읽어서 실행한다. 
break[n] '루프'부분 내용 참조 
현재 쉘 내에서 프로그램을 실행한다.(source 명령어와 동일) 
alias 별명의 목록을 출력하거나 새로 생성한다. 
bg 작업을 백그라운드로 보낸다 
bind  readlind 함수나 매크로에 대한 현재 키와 함수 바인딩, 바인드 키를 보여준다. 
break  가장 안쪽의 루프를 탈출한다 
builtin [sh-builtin [arg]]  내장 명령어를 실행시킨다. 인자를 전달할 수 있으며, 종료 상태를 0으로 반환한다. 함수와 내장 명령어의 이름이 같은 경우 유용하다. 
cd [arg]  인자를 지정하지 않으면 홈 디렉토리로 이동한다. 
command command [arg]  함수와 동일한 이름일지라도 명령어를 실행한다.(함수를 찾아보는 과정이 생략됨) 
continue [n]  루프의 내용을 참고하라. 
declare [var]  모든 변수를 보여주거나, 특정 속성을 지정하여 변수를 선언한다. 
dirs  pushd 이후에 현재 기억된 디렉토리의 목록을 보여준다. 
disown  작업 테이블에서 활성 작업을 제거한다. 
echo [args]  인자를 반향(echo)한다. 
enable  쉘 내장 명령어를 활성화하거나 비활성화 
eval [args] 실행 전에 명령행의 내용을 두 번 검사하게 한다. 한 번은 쉘이 인자로써 해석하고, 또 한 번은 명령어로써 실행한다.

exec command 현재 쉘에서 명령어를 실행한다.
exit [n] 종료 상태를 n으로 반환하고, 종료한다.
export [var] 자식 쉘에게 var를 상속한다. 
fc  히스토리 목록을 편집하기 위한 명령어(fix command) 
fg  백그라운드 작업을 포그라운드로 가져온다. 
getopts  명령행에서 지정한 유효한 옵션을 추출하기 위해 스크립트에서 사용한다. 
hash  명령어의 빠른 수행을 위해, 내부 해시 테이블을 제어한다. 
help [command]  내장 명령어에 대한 도움말을 제공한다 
history  히스토리 목록을 행 번호와 함께 출력한다. 
jobs  백그라운드의 작업 목록을 출력한다. 
kill [-signal process] 지정한 PID번호나 작업 번호에 시그널을 보낸다. kill -l 참조 
let  산술식을 평가하거나 산술 계산의 결과를 변수에 저장하기 위해 사용한다. 
local  변수의 통용범위를 함수 내로 제한하기 위해 사용한다. 
logout  로그아웃 
popd  디렉토리 스택의 항목을 제거한다. 
pushd 디렉토리 스택에 항목을 추가한다.
pwd  현재 작업 디렉토리를 보여준다. 
read [var] 표준 입력에서 읽은 내용을 변수 var에 저장한다. 
readonly [var] 변수  var를 읽기 전용으로 만든다. 변수 var를 재설정할 수 없다.
return [n] 종료 상태를 n의 반환하고, 함수로부터 복귀한다. 
set  옵션과 위치 인자를 설정한다. 
shift [n] 위치 인자를 지정한 n회 만큼 왼쪽으로 이동시킨다. 
stop pid 지정한 pid의 프로세스를 중지한다.halt
suspend 현재 쉘의 수행을 정지시킨다. 
test 파일 유형이나 조건식을 평가한다. 
times 현재 쉘에서 수행된 프로세스들의 수행시간에 대한 정보를 출력한다.
trap [arg] [n] 쉘은 시그널 n에 대해 arg를 수행한다.
type [command] 명령어의 유형을 출력한다. 
typeset 변수의 설정이나 속성을 지정한다. declare와 동일하다 
ulimit  프로세스가 사용할 수 있는 자원의 최대 한계를 설정한다. 
umask [octal digits] 파일 생성 시에 적용할 권한(소유자, 그룹, 다른 사람)을 설정한다. 
unalias  별명의 설정을 해제한다. 
unset [name]  변수나 함수의 설정을 해제한다. 
wait [pid#n] 백그라운드에서 수행되는 지정한 pid의 프로세스가 종료할 때가지 스크립트를 중지한다. 

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

쉘 프로그래밍 강좌  (2) 2012.02.09
쉘스크립트 조건문  (7) 2012.02.08
쉘스크립트  (1) 2012.02.08
#!/bin/sh  (3) 2012.02.08
Posted by GUCCI
, |
쉘 프로그래밍 강좌

참고서적 :  초보자용 리눅스 프로그래밍
            ( 대림출판사, 한동훈,이만용역, 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
        문장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

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

쉘 내장 명령어  (2) 2012.02.14
쉘스크립트 조건문  (7) 2012.02.08
쉘스크립트  (1) 2012.02.08
#!/bin/sh  (3) 2012.02.08
Posted by GUCCI
, |

1. /etc/profile - 콘 쉘이 로그인 쉘로 지정된 모든 사용자가 로그인할 때마다 이 파일을 읽는다.

2. $HOME/.profile - 콘 쉘이 로그인 쉘로 지정된 사용자가 로그인할 때마다 홈 디렉토리에 파일이 있으면 읽는다.

3. $HOME/.kshrc - 콘 쉘이 로그인 쉘로 지정된 사용자가 로그인할 때마다 $HOME/.profile파일에서 따로 설정이

                            되어 있으면 추가로 읽는 파일이다.

 

$0 - 쉘 스크립트의 이름

$1 - $9 - 첫 번째 아규먼트,두 번째 아규먼트, ... , 아홉번 째 아규먼트

${10} - ${n} - 열 번째 아규먼트, 열한 번째 아규먼트, ... ,n번째 아규먼트

$# - 아규먼트의 개수

$@ - 쉘 스크립트에 입력된 모든 아규먼트

$* - 쉘 스크립트에 입력된 모든 아규먼트

 

조건문

본쉘                                  콘쉘                                              의미

[-r file_name]          [[-r file_name]]           file_name의 내용을 읽을 수 있는지 검사

[-w file_name]        [[-w file_name]]          file_name의 내용을 변경할 수 있는지 검사

[-x file_name]         [[-x file_name]]           file_name을 실행할 수 있는지 검사

불가능                    [[-O file_name]]          file_name의 소유주가 스크립트를 실행하는 사람인지 검사(Owner)

불가능                    [[-G file_name]]          file_name의 그룹 소유주가 스크립트를 실행하는 사람이 속한 그룹인지 검사

[-f file_name]          [[-f file_name]]           file_name이 일반적인 파일인지 검사

[-d file_name]         [[-d file_name]]          file_name이 디렉토리인지 검사

[-c file_name]         [[-c file_name]]          file_name이 캐릭터 디바이스 파일인지 검사

[-b file_name]         [[-b file_name]]          file_name이 블록 디바이스 파일인지 검사

불가능                    [[-L file_name]]          file_name이 심볼릭 링크인지 검사

[-s file_name]         [[-s file_name]]          file_name의 크기가 0보다 큰 값인지 검사

불가능                    [[-e file_name]]          file_name이 존재하는지 검사(Exist)

 

본쉘                                       콘쉘                                               의미

[$num1 -eq $num2]        ((num1 == num2))         num1과 num2가 같은 값인지 검사(equal)

[$num1 -ne $num2]        ((num1 != num2))          num1과 num2가 다른 값인지 검사(not equal)

[$num1 -lt $num2]          ((num1 < num2))          num1이 num2보다 작은 값인지 검사(Less than)

[$num1 -gt $num2]         ((num1 > num2))          num1이 num2보다 큰 값인지 검사(greater than)

[$num1 -le $num2]         ((num1 <= num2))         num1이 num2보다 작거나 같은 값인지 검사(less than or equal)

[$num1 -ge $num2]        ((num1 >= num2))         num1이 num2보다 크거나 같은 값인지 검사(greater than or equal)

 

본쉘                               콘쉘                                   의미

[str1 = str2]             [[str1 == str2]]                 str1과 str2가 같은 값인지 검사

[str1 != str2]            [[str1 != str2]]                  str1과 str2가 다른 값인지 검사

불가능                    [[str1 == pattern]]             str1이 pattern으로 표현할 수 있는지 검사

불가능                    [[str1 != pattern]]              str1이 pattern으로 표현할수 없는지 검사

[str1 < str2]            [[str1 < str2]]                   str1과 str2를 사전 순으로 비교하여 str1이 앞서 있는지 검사

[str1 > str2]            [[str1 > str2]]                   str1과 str2를 사전 순으로 비교하여 str2가 앞서 있는지 검사

[-z str2]                 [[-z str2]]                        str1의 길이가 0인지 검사

[-n str2]                 [[-n str2]]                        str1의 길이가 1이상인지 검사

 

본쉘              콘쉘                                        의미

-o                 ||                     양쪽 조건 중 어느 하나만 만족하면 모든 조건이 만족

-a                 &&                    양쪽 조건 모두 다를 만족하면 모든 조건이 만족

!                                           조건이 결과 값을 반대로 바꿈

 

 

if문 - 조건의 진리 값이 참인 경우와 거짓인 경우로 나누어서 어느 부분을 선택하여 실행할 것인지를 결정                           

if 조건문                                          if 조건문                                      if 조건문

then                                                then                                           then

    명령어들              ->                           명령어            ->                       명령어

fi                                                    else                                           elif 조건문

                                                            명령어                                  then

                                                      fi                                                     명령어

                                                                                                       else

                                                                                                           명령어

                                                                                                        fi

Case문 : if문의 또다른 형태

case value in

pattern1|pattern2)

        명령어

         ;;

pattern3|pattern4)

        명령어

         ;;

pattern5|pattern6)

         명령어

         ;;

*)

         명령어

         ;;

esac

 

for문 : 미리 정해진 횟수를 반복할 때 사용

for var in list_of_value

do

      명령어

done

 

while문 : 조건을 만족하는 동안 반복하는데 사용

while 조건문

do

    명령어

done

 

until문 : 조건이 만족되지 않은 동안에만 반복한다.

until 조건문

do

    명령어들

done

 

select문 : 메뉴를 만들고 사용자가 메뉴에서 선택한 값에 따라서 명령어를 실행할 때 사용

select var in list_of_value

do

   명령어들

done

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

쉘 내장 명령어  (2) 2012.02.14
쉘 프로그래밍 강좌  (2) 2012.02.09
쉘스크립트  (1) 2012.02.08
#!/bin/sh  (3) 2012.02.08
Posted by GUCCI
, |
주석문 
'#'로 시작하는 줄. 
줄의 중간에 '#'이 와도 주석으로 인식하지만 다음과 같이 이상하게 동작하는 
경우가 발생한다. > 
코드:

    #!/bin/sh
    AA=abcd     # 여기는 주석.
    BB=${AA}kkk
    echo ${BB}

실제 원하는 출력은 "abcdkkk"이지만 실제 출력은 "abcd kkk"가 되어 버린다. 
즉, abcd뒤쪽의 공백문자가 포함되어 버린다. 
따라서 줄의 중간에 '#'을 넣어서 주석을 만들지는 말것. 
실제 test를 해보니까 그렇지 않는 것 같다(bash-2.05b). 


Shell Script 실행하기 
코드:

    1. $ source sample
    2. $ . sample
    3. $ bash sample
    4. $ chmod +rx sample;./sample  // #!/bin/bash 포함.
        모드를 변경할때 rx를 주어야 한다. shell scripts는 shell에서 읽어서
        수행해야 하므로 read 속성이 주어져야만 한다.

위에서 1, 2번 그리고 3,4번은 실행이 다르다. 1,2번은 기존에 존재하던 shell에서 
스크립트를 수행하고 3,4번은 새로운 셀을 생성해서 실행하게 된다. 이 경우에 
문제가 되는것은 스크립트 내부에서 "exit 0"과 같은 명령을 사용하면 1, 2번의 
경우는 현재 shell이 닫혀버린다. 

그리고 또하나의 문제는 1,2번의 경우는 현재 shell에서 이어져서 수행되므로 
스크립트 내부에서 사용한 변수나 함수들이 그대로 남아있다. 하지만 3,4번의 
경우는 현재 셀의 서브셀로 수행되므로 스크립트가 종료된후에는 스크립트내부의 
변수나 함수는 현재 셀에서 유효하지 않게 된다. 

따라서 수행하는 스크립트의 변수나 함수를 현재 셀에서도 유효하게 할때는 
". sample" 나 "source sample"를 사용하고 그냥 스크립트를 수행하고 종료시킬때는 
"bash sample" 나 "./sample"를 사용 



매직넘버 
리눅스에서는 기본 셀인 배쉬이외에도 다양한 종류의 셀을 사용할 수 있다. 
따라서 배쉬용 셀스크립트가 씨셀에서 실행된다면 오류가 발생할 수 있다. 
따라서 스크립트 파일의 처음 행에 파일을 실행시키는데 사용할 셀의 절대 
경로를 아래와 같이 표시하게 된다. 
코드:

    #!/bin/bash

이 매직넘버는 수행을 의미하므로 다음과 같이 사용할 수도 있다. 다음은 자기 
자신을 출력하는 shell script이다. 
코드:

    #!/bin/cat

이 파일은 스스로를 출력하는 셀스크립트이다. 



셀스크립트 확인하기 
코드:

    $ file sample

결과는 ASCII가 아니라 C 스크립트 파일로 나타난다. 



변수의 사용 
$A A라는 변수 
이렇게 사용하는 것은 지양하도록 한다. 만약 A라는 변수가 정의되지 
않았을때 완전히 공백이 되어 버리기 때문에 다음과 같은 경우에 
에러가 발생한다. 
코드:

            if [ $A = '1' ];then
                echo "A is 1"
            fi


${A} A라는 변수 
"$A" A라는 변수 
'$A' '$A'라는 스트링 
\$A '$A'라는 스트링 
`$A` A라는 변수명의 명령의 실행. 
`AA` AA라는 명령의 수행.(이식성이 강한 오래된 관습) 

다음과 같이 사용할 경우 
코드:

                AA=`AA`
                BB=$(AA)kkk
            


BB는 다음과 같이 확장된다. 
코드:

                BB=`AA`kkk
            


따라서 다음과 같이 사용하는 방법을 고려해 볼 것. 
코드:

                AA=$(shell AA)
                BB=$(AA)kkk
            


AA는 명령이 수행된후 곧바로 확장되게 된다. 

$(AA) AA라는 명령의 수행. 

$(shell AA) AA라는 명령의 수행. 


변수에 값을 대입하기 
코드:

    <case1> AA = "3333"     (X)
    <case2> BB="3333"       (O)

<case1>과 <case2>는 차이가 없어 보이지만 엄청난 차이가 존재한다. shell은 위 
명령을 수행하면서 <case1>의 경우는 'AA'라는 명령을 수행하면서 그 파라메터로 
'='와 "3333"을 대입하는 것으로 처리한다. 따라서 결과는 'AA'라는 명령이 없다고 
출력된다. 
<case2>의 경우는 shell이 'BB'라는 변수에 "3333"을 대입하는 것으로 정확하게 
인식한다. 따라서 <case2>의 경우가 정확한 표현이다. 즉 '='의 양쪽을 띄어쓰지 
않는다. 


변수의 확장의 방지 
코드:

    #!/bin/sh
    #출력이 0_tmp, 1_tmp라고나오길 기대하지만 shell은 i_tmp라는 변수가
    #존재하지 않으므로 공백을 출력하게 된다.
    for i in 0 1 2
    do
        echo $i_tmp
    done

    #정상적으로 된 경우. 변수를 확장하지 않으므로 0_tmp, 1_tmp, 2_tmp가 출력.
    for i in 0 1 2
    do
        echo ${i}_tmp
    done

    #두번째 방법
    for i in 0 1 2
    do
        echo $i{_tmp}
    done



조건 제어구문 
코드:

    if, case, while, for, until

    if test     조건
    then        명령어
    fi

    if test; then
    fi

    if test     조건
    then        명령어
    else        조건을 만족하지 않았을때 실행할 명령어
    fi

    if test     조건
    then        명령
    elif test   조건
    then        명령
    else        명령
    fi

    다음과 같은 에러메세지가 발생하는 이유는 다음과 같다.
        [: =: unary operator expected
    비교하는 파라메터를 ""로 감싸주지 않았을 때 만약 파라메터가 NULL
    String이라면 다음과 같이 취금되어 버린다.
        if [ = "yes" ]
    따라서 파라메터는 무조건 다음과 같이 ""로 감싸서 처리해주어야 한다.
        if [ "$timeofday" = "yes" ]
        if [ "" = "yes" ]



조건의 Test 
test or [] 
[]를 사용할때는 '['와 ']'와 조건사이에 빈칸을 삽입해야만 한다. 



true와 false 
셀스크립트의 조건문에서 참은 0을, 거짓은 0이 아닌값을 의미한다. 

코드:

    # true
    # echo $?
    0

    # false
    # echo $?
    1

    if true; then
    fi

    if faluse; then
    fi


조건문의 논리를 단순화하기 위해 true를 대신하는 별칭으로 ':'를 종종 
사용한다. 

코드:

    if :;then
    fi



함수의 실행결과(반환값)을 조건문에 대입하기 
잘못된 예1 > 
코드:

    exe_command
    if [ $? ]; then
        # 0이 아닌 어떤 반환값에 대해서도 들어올 것 같은데
        # 실제로는 모든 반환값에 대해서 이곳으로 들어온다. 따라서 잘못된
        # 예제이다.
        echo return value is true.
    fi


잘못된 예2 > 
코드:

    RET=`exe_command`
    if [ RET = 0 ];then
        # RET에는 exe_command의 반환값이 아니라 stdout 출력값이 들어가게 된다.
        # 따라서 위 문장은 정확한 표현이 아니다.
        echo return value is true
    fi


맞는 예1 > 
코드:

    exe_command
    if [ $? -eq 0 ]; then
        echo return value is true.
    fi


맞는 예2 > 
코드:

    if exe_command; then
        echo return value is true.
    fi


맞는 예3 > 
코드:

    exe_command
    case $? in
        0)
            echo "return zero";;
        1)
            echo "return one";;
        *)
            echo "unknown return value";;
    esac



if문 
코드:

    if [ -f ~/.bashrc ]; then
        . ~/.bashrc
    fi

    if [ -f ~/.bashrc ]
    then
        . ~/.bashrc
    fi


테스트 조건 파일 옵션 

    -b 디스크 드라이브와 같은 Block형 장치 
    -c 터미널, 프린터, 네트워크같이 Character형 장치 
    -d 디렉토리 
    -e 존재한다.(이식적이지 않으므로 -f를 사용한다.) 
    -f 일반파일 
    -k 스티키비트가 설정됨 
    -p 네임드 파이프의 형태 
    -r 읽기 권한이 허가된 상태 
    -s 사이즈가 0이 아님 
    -w 쓰기 권한이 허가된 상태 
    -x 실행 권한이 허가된 상태 
    -L 심벌릭 링크의 형태 
    -S 소켓의 형태 

만약 위 조건의 NOT일때는 "[ ! -f abcd.txt ]"가 된다.~ 


논리 연산 옵션 

    -a 논리적 AND 
    -o 논리적 OR 
    ! 논리적 NOT 


정수 비교 옵션 

    -eq Equal(=) 
    -ge Greater then or Equal to(>=) 
    -gt Greater then(>) 
    -le Less then or Equal to(<=) 
    -lt Less then(<) 
    -ne Not Equal(!=) 


문자열 비교 옵션 

    -n 문자열의 길이가 0이 아니다. 
    -z 문자열의 길이가 0이다. 
    = 두 문자열이 같다. 
    주의할점은 "=="와 혼동하지 말것. 
    != 두 문자열이 같지 않다. 


문자열 비교시 주의할 점. 
"[ $S1 = $S2 ]"와 같이 사용하면 $S1이나 $S2가 비어있다면 에러가 
발생한다. 따라서 다음과 같은 방법을 사용한다. 
"[ x$S1 = x$S2 ]" 혹은 [ "$S1"="$S2" ] 


while 문 
while 조건에 준하는 명령 
do 실행할 명령어 
done 


case 선택 제어문 
코드:

    #!/bin/sh
    case "$FLAG" in
        +)  exit;;                                  --> '+'이면 종료.
        [aeiou] ) echo -e "you inputvowel\n" ;;     --> aeiou이면 출력.
        *) echo -e "you input consonant\n" ;;       --> 그이외.
    esac


코드:

    #!/bin/sh
    echo "Is it morning? Please answer yes or no"
    read timeofday
    case "$timeofday" in
        yes | y | Yes | YES )
            echo "Good Morning";;
        n* | N* | [nN][oO])
            echo "Good Afternoon";;
        *)
            echo "Sorry, answer not recognized";;
    esac


for 반복 제어문 
코드:

    for TEMP in A B C D
    do
        echo $TEMP
    done


코드:

    # /etc/passwd의 각 행에 대해서 수행.
    for LINE in `cat /etc/passwd`
    do
        echo $LINE >> backup
        echo $LINE
    done


for문에 유용한 seq 명령어 
코드:

    # seq 1 3
    1
    2
    3


코드:

    #!/bin/sh
    for temp in `seq 1 3`; do
        echo $temp
    done



until 반복제어문 
명령을 먼저 실행한 후에 조건을 검사한다. 

코드:

    until [ "`who | grep jarrett`"]
    do
        echo "hacker is NOT logged in"
        sleep 1
    done
    echo -e "Notorious Hacker jarrett appeared at \a" `date`



and 리스트 
코드:

    statements1 && statements2 && statements3 && statements4
    if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo "there"
    then
        echo "all is true"
    else
        echo "there is one false"
    fi



or 리스트 
코드:

    statement1 || statement2 || statement3 || statement4

    if [ -f file_one ] || echo "hello" || echo "there"
    then
        echo "there is true more one.
    else
        echo "all is false"
    fi



문장블럭 
코드:

    get_confirm && {
        grep -v "$cdcatnum" $tracks_file > $temp_file
        cat $temp_file > $tracks_file
        echo 
        add_record_tracks
    }



쉘스크립트와 함수 
쉘스크립를 명령어 라인에서 직접 실행하면 서브셀이라 불리는 셀의 복사가 
기동되어 스크립트안의 처리는 서브셀에서 한다. 서브셀과 원래 셀의 현재 
디렉토리는 독립되어 있으므로 스크립트안에서 아무리 혅 디렉토리를 변경해도 원래 
쉘의 디렉토리에는 영향을 주지 않는다. 한편, 함수의 경우는 원래 쉘에서 그대로 
실행되므로 현재 디렉토리의 변경에 효과적이다. 
("source"나 "."로 쉘스크립트를 실행하면 현재 쉘에서 수행된다.) 
방법 : 함수를 저장하고 있는 파일을 ". func.txt"라고 실행시키면 함수가 현재 
쉘에 등록된다. 


함수의 사용 
함수를 사용할 때 주의 사항은 함수명과 뒤쪽의 '{'사이에는 반드시 공백이 
존재해야 한다. 
function이라는 단어는 생략이 가능하다. 
코드:

    #!/bin/sh
    # function foo() {...
    function foo(){
        echo "Function foo is executing"
    }

    echo "ScriptStarting"
    foo
    echo "Script Ended"
    exit 0


    # function foo() {...
    foo() { echo JAY;}
    result=$(foo)



함수에서 인자를 받기 
코드:

    #!/bin/sh

    function quit() {
        exit
    }

    function e() {
        echo $1
    }
    e Hello
    e World
    quit



함수의 반환값 이용하기 
1. 숫자값을 반환하기. 
코드:

    function func() {
        return 0
    }
    
    result=$(func)


2. 문자 스트링을 반환하기 
코드:

    function func() {
        echo kkk
    }

    result=$(func)


: 명령 
코드:

    while :     -> 무한 루프( while true와 동일하다)
    null 명령
        if 조건 ;then
            :
        else
            명령
        fi


local 키워드 
함수내부의 지역 변수를 선언할때 사용. 
local var="aldfjas" 

코드:
    
    #!/bin/sh
    sample_text="global variable"
    foo(){
        local sample_text="local variable"
        echo "Function foo is executing"
        echo $sample_text
    }

    echo "script starting"
    echo $sample_text

    foo



eval 
인수를 평가하게 해준다. 

    foo=10 --> foo <- 10 
    x=foo --> x <- foo 
    y='$'$x --> y <- $foo 
    echo $y --> $foo가 출력 

    foo=10 --> foo <- 10 
    x=foo --> x <- foo 
    eval y='$'$x --> y <- $foo 
    echo $y --> $foo인 10이 출력 


exec 
현재 셀을 다른 프로그램으로 대체한다. 

    exec echo "asljfasldfkasdlf" --> exec 아래의 명령은 실행되지 않는다. 



exit n 
스크립트의 반환값을 지정한다. 만약 종료상태를 지정하지 않고 종료한다면 
마지막에 실행된 명령의 반환값으로 사용될 것이다. 

    반환값 0 : 성공 
    1 ~ 125 : 스크립트에 의해 사용될 수 있는 값. 
    126 : 파일이 실행 가능하지 않다. 
    127 : 명령이 발견되지 않았다. 
    128이상 : 시그널이 발생했다. 


printf 
최신 셀에서만 유효하다. 
코드:
    
    printf "format string" paramerter1 parameter2
    printf "%s\n" hello
    printf "%s %d\t%s" "Hi There" 15 Peopel



    \\ : 백슬래쉬 
    \a : 경고 
    \b : 백스페이스 
    \f : 폼피드 
    \n : 새줄 
    \r : 개행 
    \t : 수평탭문자 
    \v : 수직탭문자 
    \000 : 8진수 값을 가지는 한 문자 


set 명령 
set 명령은 쉘을 위한 파마메터 변수를 설정한다. 이것은 빈칸으로 구분되는 
값을 출력하는 명령에서 필드를 사용하는 유용한 방법이 될 수 있다. 

코드:

    # date의 출력결과가 "2003. 06. 22. (일) 19:54:41 KST"일때.

    set $(date)



    # $0 -> date 명령을 지시하지 않고 현재 쉘스크립트의 이름을 지시한다. 
    # $1 -> "2003." 
    # $2 -> "06." 
    # $3 -> "22." 
    # $4 -> "(일)" 
    # $5 -> "19:59:06" 
    # $6 -> "KST" 


shift 
$2 -> $1 
$3 -> $2 


trap 
시그널(signal)을 받아들일 때 수행하는 동작을 지정하는 데 사용된다. 
[list] 
trap `rm -f /tmp/my_tmp_file_$$` INT 
--> INT(CTRL+C)가 발생하면 수행하는 명령. 
trap - INT --> trap해제. 
[list] 

명령의 수행 

    `명령` : 이식성이 강한 오래된 관습. 
    $(명령) : 



산술 확장 

echo $((1+1) 
echo $(( 1 + 1 )) 
echo $[1+1] 
echo $[ 1 + 1 ] 
echo `echo 1+1 | bc -l` 
코드:

    $(())

    #!/bin/sh
    # 주의할 점은 "x = $(($x+1)"이라고 '=' 양쪽을 띄어쓰지 않는다.
    x=0
    while [ "$x" -ne 10 ]; do
        echo $x
        x=$(($x+1))
    done


    #!/bin/sh
    x=0
    while [ "$x" -ne 10 ]; do
        echo $x
        let x = $x + 1
    done


    #!/bin/sh
    x=0
    while [ "$x" -ne 10 ]; do
        echo $x
        let x-=1
    done


    #!/bin/sh
    i=0
    while [ "$i" -ne 10 ]; do
        filename=`printf %06d.jpeg "$i"`
        echo "$filename"
        sleep 1
    done]


toggle 상태 만들기. 
코드:

    val=0
    while true; do
        echo $val
        # 주의할 점은 '=' 양쪽에 공백이 들어가서는 안된다.
        val=$(( 1 - $val))
        # 혹은 "let val= 1 - $val"
        sleep 1
    done



파라미터 변수 
[list] 
$1,$2,... 스크립트에 주어진 파라미터 
"$9"보다 큰 매개변수는 "${10}"와 같이 "{}"로 감싸주어야 한다. 

$* 환경변수 IFS의 첫문자로 구분되고, 하나의 변수에 저장되는 모든 
파라미터의 목록, 만약 IFS가 NULL이면 모든 파라메터가 붙어서 
나온다. 

$@ IFS 환경변수를 사용하지 않는 $*에 대한 변형 
"$*"와 "$@"중에서 "$@"를 사용하는 것을 권장한다. 

echo `basename $0` 
실행된 스크립트에 "./"가 붙어있는 경우에 떼어내고, 스크립트 
이름만을 출력한다. 
[list] 

파라메터 확장 

    ${param:-default} 
    param이 널이 아니면 param을 반환하고 널(혹은 존재하지 않으면)이면 
    default의 값을 반환한다. 이 경우에도 param의 값은 변하지 않는다. 
    ${param:=bar} 
    만약 param이 널이 아니면 param을 반환하고 널이면 param에 bar를 넣고 
    param을 반환한다. 이 경우에 param의 값이 bar로 변경된다. 
    ${param:+bar} 
    param이 존재하고 널이 아니면 bar의 값으로 설정하고 널이면 널을 반환한다. 
    어떤 경우에도 param값은 변경되지 않는다. ${param:-default}와 반대로 
    동작한다. 
    ${#param} 
    param의 길이를 제공한다. 
    ${param#word} 
    앞에서부터 가장 먼저 word가 일치하는 부분까지를 제거한 나머지 부분을 
    반환한다. 
    ${param##word} 
    앞에서부터 가장 나중에 word가 일치하는 부분까지를 제거한 나머지 부분을 
    반환한다. 
    ${param%word} 
    끝에서부터 가장 먼저 word가 일치하는 부분까지를 제거한 나머지 부분을 
    반환한다. 
    ${param%%word} 
    끝에서부터 가장 나중에 word가 일치하는 부분까지를 제거한 나머지 부분을 
    반환한다. 
    ${param:?bar} 
    param이 널이 아니면 param을 반환하고 param이 널이면 "param: bar"를 
    출력하고 현재 셀이 종료된다. 만약 기존의 셀에서 서브셀로 수행된 
    스크립트라면 현재 셀이 종료되고 그렇지 않고 기존의 셀에서 이어져서 
    수행되었다면 "param: bar"를 출력하고 계속 수행한다. 


예제. 
코드:
    
        #!/bin/bash

        unset foo
        echo ${foo:-bar}

        foo=fud
        echo ${foo:-bar}

        foo=/usr/bin/X11/startx
        echo ${foo#*/}          // *는 0이상의 어떤 문자를 의미한다.
        echo ${foo##*/}

        bar=/usr/local/etc/local/networks
        echo ${bar%local*}
        echo ${bar%%local*}

    출력
        bar
        fud
        usr/bin/X11/startx
        startx
        /usr/local/etc/
        /usr/



shell script에서 2진수 계산하기 
코드:

    # 128과 180의 OR값 구하기
    let 'result = 128 & 180'
    echo $result

    # bc로 리다이렉션해서 x180을 2진수로 변환한 결과를 출력한다.
    # ibase : 입력의 진수(2|8|10|A)
    # obase : 출력의 진수(2|8|10|A)
    echo 'ibase=A;obase=2;180'|bc



Here Document 
코드:

    cat << !FUNKY!      --> Here document로 cat에 전달한다.
    hello
    this is a here
    document
    !FUNKY!             --> Here document끝.


>>>> 동작은 cat으로 "!FUNKY!"사이의 글자를 전달하는 역할을 한다. 


ed a_test_file << !FunkyStuff! --> ed editor Here document로 입력한다. 


.,\$s/is/was/ 


!FunkyStuff! --> here document끝. 



Scrip 디버깅 
코드:

    sh -n <script>      set -o noexec       형식에러만을 확인한다.
                        set -n              명령을 실행하지 않는다.
    sh -v <script>      set -o verbose      실행하기 전에 명령을 출력한다.
                        set -v
    sh -x <script>      set -o xtrace       명령라인에서 처리한 후에 명령을
                        set -x              출력한다
                        set -o nounset      정의되지 않은 변수가 사용될
                        set -u              때 에러 메시지를 제공한다.



조건 제어관련 셀명령 

    break for, until, while 루프를 빠져 나온다. 
    continue 루프를 계속 진행. 
    echo 표준 출력(1)으로 입력된 내용을 출력. 
    exec 현재의 셀을 이용해서 명령어를 실행시킨다. 
    exit 현재의 셀을 종료한다. 
    let 산술연산과 논리연산을 수행한다. 
    read 표준 입력(0)을 통해서 입력을 받는다. 
    return 함수를 종료한다. 
    test [] 조건을 검사한다. 
    `명령어` 명령어를 실행하고 그 결과를 대입한다. 


exit와 return 
exit는 현재 쉘스크립트를 종료하는 역할을 하고 return은 함수나 sourced 
script(?)에서만 반환하는 경우에 사용한다. 


배열의 사용 
bash의 새 버전부터는 1차원 배열을 지원한다. variable[xx]처럼 선언할 수도 있고 
'declare -a variable'처럼 직접적으로 지정해 줄 수도 있다. 배열 선언을 
역참조하려면(내용을 알아내려면) ${variable[xx]}처럼 중괄호 표기법을 사용하면 
된다. 


재지향 
파일 디스크립터 

    0 : 표준 입력 
    1 : 표준 출력 
    2 : 표준 에러 


코드:

    cat 2>&1    # 표준 에러를 표준출력으로 같이 보낸다.

    make 1>a.a 2>&1
        make의 결과를 a.a로 그리고 error 출력도 a.a로 보낸다.
    



C style의 문자열의 해석 
코드:

    # echo '111\n222\n333\n'
    111\n222\n333\n

코드:

    # echo $'111\n222\n333\n'
    111
    222
    333

위 예제에서 볼 수 있듯이 $"" 안에 들어간 문자열은 C의 문자열에서와 같이 
\t,\n,\r등이 해석된다. 
따라서 다음과 같이 사용할 수 있다. 
코드:

    # find . -type f -exec vi -c $'20,30d\nwq\n' \{} \;

파일에 대해서 20~30행을 제거하는 명령이다. 


예약된 종료코드 


    정상종료. 


    광범위한 일반적 에러 
    let "var1 = 1/0" 
    "divide by zero"같은 잡다한 에러 


    bash 문서에 명시되어 있는 쉘 내장명령어의 오사용 
    거의 보기 힘들고 보통은 디폴트로 1번 종료 코드로 나타남 

    126 
    실행 불가능한 명령어의 구동 
    퍼미션 문제거나 실행 허가가 없는 명령어 

    127 
    "command not found" 
    $PATH 문제거나 오타일 가능성 있음 

    128 
    exit에 잘못된 인자 넘김 
    exit 3.14159 
    exit는 0에서 255사이의 정수만 받음 

    128+n 
    치명적 에러 시그널 "n" 
    kill -9 스크립트의 $PPID 
    $?는 137 (128 + 9)을 리턴 

    130 
    스크립트가 Control-C에 의해 종료됨 
    Control-C 는 치명적 에러 시그널 2번(130 = 128 + 2, 바로 위 참고) 

    255 
    종료 상태 범위 초과 
    exit -1 
    exit는 0에서 255사이의 정수만 받음 


저자가 제안하는 방법은 사용자 정의 종료 코드를 64 - 113(성공시 0도 
포함)으로 제한해서 C/C++ 표준을 따르는 것입니다. 이렇게 해도 사용자는 
여전히 50개의 코드를 쓸 수 있는 있기 때문에 나중에 스크립트의 문제를 좀 더 
깔끔하게 해결할 수 있습니다. 


지역화(Localization) 
지역화된 쉘스크립트는 시스템의 로케일에 따라 정의된 언어로 텍스트를 
출력하게 해준다. 

코드:

    #!/bin/bash
    # localized.sh
    E_CDERROR=65
    error()
    {
      printf "$@" >&2
      exit $E_CDERROR
    }
    cd $var || error $"Can't cd to %s." "$var"  #문자열들을 $""로 묶어준다.
    read -p $"Enter the value: " var


    bash$ bash -D localized.sh
    "Can't cd to %s."
     "Enter the value: "
    # -D옵션은 스크립트를 수행하지 않고 $뒤에서 큰따옴표로 묶인 문자열을
    # 보여준다.


    bash$ bash --dump-po-strings localized.sh
    #: a:6
    msgid "Can't cd to %s."
    msgstr ""
    #: a:7
    msgid "Enter the value: "
    msgstr ""
    # --dump-po-strings 옵션은 -D와 닮았지만 gettext의 "po" 포맷을 사용한다.


    # ko.po 파일 내용.
    #: a:6
    msgid "Can't cd to %s."
    msgstr "%s 디렉토리로 옮겨갈 수 없습니다."
    #: a:7
    msgid "Enter the value: "
    msgstr "값을 넣으세요: "
 

    # msgfmt실행.
    bash$msgfmt -o localized.sh.mo ko.po


    # localized.sh.mo 파일을 /usr/local/share/locale/ko/LC_MESSAGES 디렉토리에
    # copy.


    # 이제 스크립트에 첫부분에 다음의 두줄을 추가.
    # TEXTDOMAIN과 TEXTDOMAINDIR 변수는 전체 환경으로 export되어야 한다.
    TEXTDOMAINDIR=/usr/local/share/locale
    TEXTDOMAIN=localized.sh



error string 
: bad interpriter 
이 에러는 쉘스크립트파일이 UNIX형식이 아닌 DOS 형식일때 이러한 에러가 
발생한다. 주의할 것. 


생각해 볼 문제 
코드:

    test -d package || ( echo 'Wrong working directory.'; exit 1 )
    [ -d package ] || ( echo 'Wrong working directory.'; exit 1 )

위 문장이 어떻게 동작할 것인가. 단순하게 생각할때는 package라는 디렉토리가 
존재한다면 문장이 출력되지 않을 것이다. 그리고 package라는 디렉토리가 존재하지 
않는다면 문장을 출력하고 스크립트를 종료하게 될 것이다. 하지만 문장을 출력하고 
종료되지 않는다. '('와 ')'로 묶인곳이 실행되면서 현재 shell이 새롭게 하나 
생성되어서 실행된다. 따라서 exit를 수행할때는 새롭게 생성된 shell이 종료되고 
현재 shell은 종료되지 않는다. 따라서 exit로 종료되지 않고 계속 수행되게 된다. 

따라서 다음과 같이 수정한다. 
코드:

    # if문 대체하기.
    if [ -d package ];then
        echo 'Wrong working directory.'
        exit 1
    fi

    # 문장 블럭 사용하기.
    # 주의할 점은 'exit 1' 다음에 ';'가 들어가 주어야 한다.
    [ -d package ] || { echo 'Wrong working directory.'; exit 1; }

    # 그냥 '('')'를 없애기
    # '||'와 ';'중에 '||'가 우선순위가 더 높아서 의도한 대로 수행된다.
    # 하지만 블럭의 구분이 모호해진다. 따라서 문장 블럭을 사용하는것이 좋을 것
    # 같다.
    [ -d package ] || echo 'Wrong working directory.'; exit 1


임시파일의 생성 

    $$ : 임의의 난수를 발생한다. 
    이 숫자값은 현재 shell에서는 계속동일한 값을 가진다. 

코드:

    #!/bin/sh

    echo "temp file" > temp_$$
    rm -f temp_$$

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

쉘 내장 명령어  (2) 2012.02.14
쉘 프로그래밍 강좌  (2) 2012.02.09
쉘스크립트 조건문  (7) 2012.02.08
#!/bin/sh  (3) 2012.02.08
Posted by GUCCI
, |

#!/bin/sh

리눅스/쉘스크립트 / 2012. 2. 8. 18:47

sh는 쉘 프로그램 해석기이다. 쉘 스크립트를 보면 첫 줄에 아래와 같은 구문을 볼 수 있다.

 

#!/bin/sh

#!/usr/bin/perl

 

해당 스트립트를 #! 뒤에 나오는 절대경로에 위치하는 쉘 프로그램의 구문 문법을 통해 해석하고 실행하나는 뜻이다. 이런 전처리 작업을 해주는 이유는 보통 스크립트는 종류도 많고 그에 따른 문법도 제각각이기 때문이다. 

 

sh는 bone shell이라고도 하며 가장 기본적인 쉘이다.

쉘이란 커널과 사용자를 연결해주는 하나의 매개체 역할을 한다고 보면 된다.

쉘은 여러가지 형태로 만들어지지만 크게 csh 계열과 ksh 계열로 나뉜다.

csh는 c 언어를 기초로 관리자 중심으로 만들어진 쉘이고

ksh는 korn shell이라고 불리며 사용자 중심으로 만들어진 쉘이다.

csh는 후에 tcsh으로 확장된다.

리눅스는 bash라는 쉘을 사용하며 이 의미는 born again shell의 의미를 가지고 있다.

bash는 csh의 관리적인 측면과 ksh의 사용자 편의성 측면을 모두 고려하여 만들어진 쉘이다.

리눅스는 대부분의 쉘을 호환하여 사용할 수 있다.

[출처] #!/bin/sh|작성자 시대유감

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

쉘 내장 명령어  (2) 2012.02.14
쉘 프로그래밍 강좌  (2) 2012.02.09
쉘스크립트 조건문  (7) 2012.02.08
쉘스크립트  (1) 2012.02.08
Posted by GUCCI
, |

최근에 달린 댓글

글 보관함