강좌
클라우드/리눅스에 관한 강좌입니다.
리눅스 분류

쉘 스크립트 입문

작성자 정보

  • 웹관리자 작성
  • 작성일

컨텐츠 정보

본문

icon01.giftitle71.gif

(Introduction to Shell Scripting--the Basics)
By Ben Okopnik
번역 :김미경/mee@linuxlab.co.kr

 

``Here’s a hint. When you think your code to exec a shell function is just not working, never, repeat NEVER send it “/etc/reboot” just to see what happens.’’
-- Elliott Evans

 

INTRO

Shell scripting은 당신에게 그 믿어지지 않는 융통성으로의 접근과 그리고 매우 간단한 도구를 가지고 Linux의 힘을 주는 예술과 과학의 매혹적인 결합입니다. PC의 옛날에 돌아와서, 나는 DOS의 “일괄처리 파일-배치파일” 을 아주 노련하게 사용했었습니다. 내가 지금 실현한 것은 약하고 알맹이 없는 Unix의 쉘 원본의 모방이었습니다. 그렇다고 해서 Microsoft의 배치파일이 별 볼일 없다는 것은 아닙니다.

쉘 scripting이 쉘 그것 자신의 풀 수 없는 부분이니까, 여기에 있는 상당히 많은 자료는 쉘 궤변, 방법, 그리고 특성으로 다룰 것입니다. 참을성 있게 봐주십시오; 그것은 좋은 스크립트를 쓰기에 필요한 지식의 모든 부분입니다.

 

SCRIPTING의 철학

Linux -- Unix in general --는 따뜻하고 보풀 같고 누구나가 사용 가능하게 의도된 시스템이 아닙니다. 당신이 수행해야 하는 정확한 실행과 연산을 명시하는 , 그것은 당신에게 결합의 문자 그대로 필요한 어떤 결과를 달성하기 위해, 무한한 수에 연결될 수 있도록 해주는 작은 도구입니다. (나는 Perl의 모토인 “TMTOWTDI” - There’s More Than One Way To Do It - 가 유닉스에도 적용된다고 생각한다.) -- 사용자에서 더 높은 능력을 원하는 복잡함과 요구사항을 증가시켰습니다. 주장, super-sonic 제트 전투기와 자전거는 극심한 차이가 있지만 표준화된 GUI의 명령을 따른 것과 당신의 자신의 프로그램이나 쉘 스크립트를을 새로 만들면서 거기에 필요로 하는 방법으로 필요한 기능을 정확히 수행하는 것 사이에는 극심한 차이가 있습니다.

쉘 scripting은 프로그래밍입니다.-- 그러나 그것은 작고 형식적인 구조를 가진 쉽게 만들어진 프로그래밍입니다. 그것은 자신의 배열을 가진 해석된 언어입니다 -- 그러나 당신의 명령행에서 프로그램을 호출할 때 당신이 이용한다는 것은 단지 그 배열입니다; 내가 “recyclable 지식”을 참조하자면 쉘 원본을 매우 유용하게 만드는 도구입니다: 그것을 사용하는 프로세스에서, 당신은 당신의 쉘의 특성과 당신의 시스템의 연산에 대해 그 이상까지를 끊임없이 배웁니다.

 

REQUIREMENTS

나는 bash에 대하여 호감을 가지고 있습니다. 그리고, 그것은 우연히 매우 일반적으로 사용되는 쉘입니다. 당신이 그 외 다른 것을 사용할지라도, 그것은 여전히 좋습니다: 당신이 `bash’를 사용한다면 이 원본은 올바르게 수행될 것입니다. 당신이 아는 것처럼 쉘은 그들이 필요로 하는 스크립트를 호출합니다; 그것은 스크립트를 실행하기 위한 부분입니다.

당신이 그것들을 나중에 발견할 수 없는 장소에서 이 파일들을 낭비하는 것을 원하지 않으므로 당신의 홈 디렉토리에 있다고 나는 가정할 것입니다. 당신의 쉘 스크립트를 한번 선택하면 타이프 친 각 라인에서 “Enter” 해주면 충분하다고 추측합니다. 당신의 path 에서 같은 이름을 실행시키면 안된다는 것을 알 것입니다. 이러한 이유 때문에 당신의 스크립트에 “test” 하면 안된다. 이것은 유닉스에서 가장 흔한 질문 중에 하나이다. “왜 쉘 스크립트나 프로그램이 작동하지 않는가?” 아마도 “test”로 호출된 /bin에 원하는 파일이 없을 것입니다.

당신이 화일 연산의 기본을 알아야 한다는 것은 말할 필요도 없습니다 - 실행, 복사,등,등., “. “ 는 현재의 디렉토리이고 “..”는 상위 디렉토리입니다. “ ~”는 당신의 홈 디렉토리입니다. 당신은 그것을 알지 못했습니까? 당신은 지금 할 수 있습니다.. 당신이 어떤 에디터를 이용하든지, mcedit 그 외 어떤 다른 편집 프로그램이라도 좋습니다. 그런데, 그것은 둘 중의하나, `vi’, `emacs’일 것입니다; 바로, 몇몇의 word-processing 포맷으로 이 작업을 저장하지 마세요. 자료의 일정한 반복을 회피하기 위해서, 우리가 작업하는 원본 화일에 나는 그 라인의 번호를 붙일 예정입니다. 어쨌든, 나는 마지막에 다같이 실행되도록 할 것입니다.

 

BUILDING A SCRIPT

스크립트를 만드는 기본으로 갑시다. 대부분의 사람들이 이 명백하고 단순한 스크립트를 다음의 진행에 따라 하다보면 점점 더 복잡해진다는 것을 알 수 있습니다.

쉘 스크립트를 간단한 형태로 말하자면 당신이 타이프하는 명령어들을 쉘 원본은 하나씩, 하나씩 나열하여 스크립트를 필요로 하는 약간의 “마법”에 한 종류입니다. 그 “마법”은 두 가지로 나누어져 있습니다. 표기법은 그것, 그리고 그것을 실행 가능하게 만들기 위해서 그 원본을 포함하는 파일의 허가를 변경을 하는데 있어서 스크립트가 그만큼 이용됩니다. 실제적인 보기로서, ‘back up’이라는 특별한 파일의 스크립트를 만들어 봅시다. 우리는 한 단계씩 실행시키므로써 통과할 것입니다.

첫번째는 허가모드가 있는 파일을 만든다.
 

>bkup
chmod +x bkup

 

(역자 주: 위에서 “>”은 프롬프트가 아님. 입력해야 함.)

처음 라인에서는 당신은 현재의 디렉토리에서 “bkup” 파일을 만들었습니다. 두번째 라인은 그것에 “+x”라는 허가모드를 주어 실행 가능하게 만듭니다 만약 제한을 두고 싶다면 허가 모드에 “u+x” 혹은 “ug+x” 로 해준다. 대부분의 경우에 “x”를 권장합니다.

다음으로 우리는 실제로 스크립트를 만들기로 합니다. 편집기를 시작하고 만들어 놓은 파일을 연다.

mcedit bkup

우리가 만드는 모든 스크립트의 첫 줄은 아래와 같아야 합니다.(맨 앞의 숫자와 콜론은 무시하시오.)

1: #!/bin/bash

이것은 ‘hash-bang hack’ 와 관계 있다고 한다. 이것에 대하여 흥미 있는 것은 실제로 파운드 문자(#)가 주석이라는 것입니다. # 이 포함된 라인은 쉘에서는 무시되는 라인이지만 “#!”의 다음에는 실행을 하는데 있어서 필요한 번역기를 지정한다는 면에서 독특하다.

우리는 실제로 그 원본을 새로 만들 필요가 있을 것입니다. 당신의 에디터를 시작하고 당신이 막 만든 화일을 여세요. 스크립트가 실행될 때 실제는 현재의 bash 프로세스가 실행되는 위에 또다른 쉘이 시작되는 것입니다. 그것에서 나갈 때 원래의 쉘로 돌아가는 것입니다..예를 들어서 쉘이 실행하면서 디렉토리를 바꾸었다면 그 쉘에서 나가도 그 새로운 디렉토리에서 있습니다. 원래의 쉘은 변경된 디렉토리를 알려주지 않습니다. 쉘을 시작한 후에 어떤 변경을 했어도 스크립트를 실행하는 동안 그 상태를 유지합니다.
스크립트를 계속합니다.

2: # “bkup” - copies specified files to the user’s ~/Backup
3: # directory after checking for name conflicts.

내가 언급한대로 ‘#’의 문자는 주석입니다. 이것은 좋은 생각이고 쉘 스크립트의 숫자도 여기에 넣을 수 있다. 어떤 포인트나 당신이 쓴 것을 기억해야 하는 것 등을 가리키고 싶을 때는 여기에 넣어 줄 수 있다.

4: cp -i $1 ~/Backup

‘cp’명령어에서 “-I”옵션은 우리가 ~/Backup 디렉토리에 존재하는 “bkup file.txt” 파일을 실행시키고 “file.txt”파일을 불러옵니다. cp는 또 기존에 있던 파일에 덮어 쓸 건지 취소할 건지를 물어보아서 “y” 키를 누르라고 요구합니다.

그 “$1”은 “위치 변수”입니다 -- 그것은 당신이 그 스크립트에 이름을 준 후에 타이프하는 첫번째 일을 표시합니다. 거기에 이 변수의 전체의 리스트가 있습니다.

$0 - 실행되는 스크립트의 이름입니다. 여기서는 “bkup”.
$1 - 첫번 파라메터입니다. 여기서는 “file.txt”
#@ - 파라메터 전체 - “$1 $2 $3...”
$# - 파라메터 개수

위치의 변수를 조절하는 방법에는 다른 여러가지의 방법이 있습니다 -- 그러나 우리는 이것을 당분간 사용할 것입니다.

 

MAKING IT SMARTER

지금까지, 스크립트는 그리 많은 역할을 하지 않았습니다. 그래도 가치가 있습니다. 그것을 더 유용하게 만듭시다. 당신이 백업 디렉토리와 새로운 디렉토리가 저장되기를 바란다면 그 아마도 버전을 보여주기 위해 다음과 같이 덧 붙여야 합니다. 그리고 그 최후의 라인을 다음과 같이 수정합니다.

4: a=$(date +%T-%d_%m_%Y)
5: cp -i $1 ~/Backup/$1.$a

여기에서, 우리는 쉘 스크립트의 힘을 볼 수 있습니다. 그 힘은”대체 명령”라고 불리는 다른 Linux 도구의 결과를 사용하는 능력입니다. $(command)는 괄호 안의 명령을 수행하고 “$(command)”의 결과를 변수에 부여합니다. 이 경우에서, date는 현재의 시간과 날짜를 나타냅니다. 그리고 ‘a’라고 불리는 변수에 그 결과를 할당하고서 ~/Backup 디렉토리에 저장하는 파일의 확장자에 이를 사용합니다. 그러나 우리는 변수 값을 사용하는 것을 원할 때, ‘$를 붙여야 합니다. 변수의 이름은 아래의 예외를 제하고 거의 어떤 것도 사용될 수 있습니다.

* 예약어는 사용할 수 없다.
  즉 case do done elif else esac fi for function if in select then until while time 들이다.

* 아래 문자는 사용할 수 없다.
  o ! { } | & * ; ( ) < > space tab

* 표준 쉘 변수명은 포함하지 않아야 한다.
   o PATH PS1 PWD RANDOM SECONDS....( “man bash” 를 참고 하라.)

내 경험에 의하면 만약 변수의 이름을 소문자, dashes(-), and underscores(_)에 한정한다면 별다른 문제는 없을 것입니다.

스크립트의 최종 두 라인의 효과는 ~/Backup 디렉토리에 다른 어떤 것과도 충돌하지 않는 유일한 파일명 -- 예를 들어 file.txt.01:00:00-01_01_2000 --을 새로 만듭니다. 이상한 어떤 이유로 두 파일명이 충돌하면 당신의 “명령 처리 프로그램”은 이를 회피할 기회를 줄 것입니다.

그런데 먼저 나온 버전은 $(command) 변수를 사용하기가 어렵습니다. 예를 들어 -$(cat$($2$(base name file1 txt))),이 변수에서 첫번째 변수 값을 실행하고 두번째 변수가 실행될 때는 예기치 않은 에러가 있을 수 있습니다. 그러나 새로운 버전으로 사용한다면 에러를 피할 수 있습니다.

그리고 우리는 읽기 쉽게 하기 위하여 여백을 더 만들어주고 라인에 숫자를 없앴습니다.
 

#!/bin/bash
# “bkup” - copies specified files to the user’s ~/Backup
# directory after checking for name conflicts.
a=$(date +%T-%d_%m_%Y)
cp -i $1 ~/Backup/$1.$a

 

이것은 오직 두 줄의 스크립트 있다. 그러나 그것은 시작하는데 유용하게 쓰입니다.

우리는 계속해서 이 주제를 가지고 논의합니다. 또 “Unix FAQ” 가 있습니다. 당신은 당신의 새로운 아래처럼 스크립트를 시작합니다.

Bkup

그러나 아래와 같은 답이 나올 것입니다.
 

bash: bkup: command not found

 

* “아니 나는 할만큼 했는데 이게 무슨 꼴이야.

dos 에서와 달리 현재의 디렉토리에서 스크립트의 실행은 가능하지 않습니다. 누군가가 “ls”라는 스크립트를 만든다고 상상해보십시오. 현재의 디렉토리에서 “ls”라는 단어를 타이프 친다면 PATH 변수가 설정되어 있지 않다면 유감스럽게도 현재의 디렉토리에서 실행은 불가합니다.

이런 이유로 인해서 스크립트를 실행시키길 원한다면 특별히 PATH를 지정해야 합니다. 당신은 또한 당신의 path에서 지정된 디렉토리를 스크립트로 제거할 수 있습니다. “/usr/local/bin” 은 좋은 예로 볼 수 있습니다.

그것을 실행시키는 간단한 명령어로는 다음이 있습니다.
 

./bkup file.txt

 

여기에서 “./”는 현재의 디렉토리에서 실행시킨다는 뜻입니다. 다른 디렉토리라면 “~/”을 사용해야 합니다. 여기에서 알 수 있는 것은 당신이 PATH 변수에서 디렉토리 지정을 정확하게 지정해야 한다는 것입니다.

이는 “file.txt”라고 불리는 파일이 당신의 홈 디렉토리에 있고 Backup라는 서브 디렉토리가 만들어져 있어야 합니다. 그렇게 하지 않으면 error 가 납니다.

 

REVIEW

위에서 쉘스크립트를 만드는데 필요한 기본 지식과 몇몇 조건을 제시합니다.

· File creation (파일 만들기)
· Permissions (파일 허가)
· Spawned subshells (다른 쉘 열기)
· Execution in a non-PATHed directory (패스설정이 안된 곳에서 실행)
· The `hash-bang hack’
· Comments (주석)
· Positional parameters (위치 파라메터)
· Command substitution (명령 대치)
· Variables (변수)

 

WRAP-UP

여기에서 우리는 시작하는데 좋은 정보를 얻었습니다. 쉘 스크립트는 리눅스에서 매우 파워풀하고 재미있는 부분입니다. 다음달에는 쉘 스크립트를 사용하는데 나올 수 있는 syntax error 에서 스크립트가 해야 하는 에러 체크와 조건부 실행, 그리고 쉘 스크립트에서 종종 사용되는 “power tools”에 대하여 논의하려고 합니다.

수정 사항이나 개선할 사항이 있으면 나에게 보내주십시오. 당신이 알고 있는 쉘 스크립트 팁이나 당신이 발견한 트릭이 있으면 나에게 알려 주십시오.

나는 항상 새로운 것을 받아들이는 학생과 비슷하다고 생각합니다.

 

Happy Linuxing!

Copyright (c) 2000, Ben Okopnik
Published in Issue 52 of Linux Gazette,
April 2000





관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,056 명
  • 현재 강좌수 :  35,910 개
  • 현재 접속자 :  259 명