스크립트 만들어 게을리 살자 (2)

매뉴얼
컴퓨터는 인간이 원하는 것중 피곤하고 짜증나는 것을 대신해 주는게 큰 목적이다. 전에도 얘기했듯이 컴퓨터가 인간을 오히려 피곤하게 한다거나, 능히 쉽게 할 수 있는 것을 어렵게 계속 하고 있는 것은 바라던게 아니겠지.

컴퓨터는 열나 단순해서 하나부터 열까지 일일히 말해줘야 한다. 그리고 뭐든지 정확히 설명해줘야 한다.
"TV를 켜라!"는 말을 들으면 사람은 바로 이해하고 어케어케해서 티비를 켜겠지만, 컴퓨터가 알아듣기 위해서는,
"TV의 전원을 넣어라" -> "TV의 리모콘이 있다면, 거기에서 전원 버튼을 찾아서, 그것에 적당한 압력을 가해 눌러라. 리모콘이 없다면 TV본체에서 전원 버튼을 찾아서, 역시 적당한 압력을 가해 눌러라" 라고 말해줘야 한다.
즉, 컴퓨터에게 일을 시키기 위해서는 컴퓨터가 얼마나 단순무식한지 알고, 인간이 습관적으로 쉽게 하는 간단한 일이 사실은 어떤 중간 과정들이 있는건지 재발견할 필요가 있다.

프로그램을 짠다는 것은 컴퓨터에게 "이러저러해라"하는 지시문을 작성하는 것인데, 좋은 프로그램은 컴퓨터 기술에 대한 지식만으로 나오지 않는다. 내게 좋은 프로그램이란, 바로 지금 내가 원하는 걸 부담없이 해주는 프로그램일 것이다.

나와 컴퓨터, 그리고 환경에 대한 이해가 바탕이 되서, 실제 일이 어떻게 이루어질(지는)지에 대한 상상력이 풍부한 사람이 좋은 프로그램을 짤 수 있다. 엄청 복잡하고 덩치만 크지, 실제로 내가 많은 추가작업을 앞뒤로 해줘야 한다던지, 지금 당장 필요한데 쓸 수 없다던지 하는 것은 "내게 좋은" 프로그램은 아니다. 가장 "내게 좋은" 프로그램은 사실 자기 자신이 만들 수 있을 거라고 본다. 만일 가능하다면, 나는 모든 컴퓨터 사용자가 프로그래머가 되는 것이 가장 바람직하다고 생각한다. 프로그램을 짜는데 있어 컴퓨터 관련 지식의 비중은 생각보다 크지 않다는 걸 말하고 싶다.

자, 그럼 서론은 슬슬 접고,
프로그램을 짜는데 있어 제일 먼저 할일은,
"내 욕망을 정확히 표현하기"이다. 난 뭘하고자 하나, 그걸 위해 뭐가 필요한가?
앞의 글에서 든 예는, "내가 지정하는 이미지들이, 폭이 넓은 이미지가 640x480보다 크면, 그 크기를 640x480으로 조정하고, 위 아래로 길쭉한 이미지가 폭이 640보다 넓으면 640x??? 사이즈로 바꾼다. 더 작은 이미지는 그냥 내버려 둔다." 이다.

그 다음은 이것이 어떻게 실제로 이루어질지 생각해본다.
먼저 1. "내가 지정하는 이미지"가 어떤 것들인지 파악하고,
2. 그것들 각각의 이미지 사이즈를 알아낸다.
3. 이미지 사이즈를 주어진 요건에 비춰 판단한다.
4. 판단에 따라 적절한 작업을 수행한다.

이정도면 됐을까? 조금 더 나눠보자. 말했든 컴퓨터는 아주 아주 바부탱이다. 빠르기만 열나 빠르지, 0이야? 1이야? 이거 밖에 할 줄 모른다. 조금 더 자세히 할 일을 말해주자.

1. 내가 지정하는 이미지들이 어떤 것인지 따로 적어놓고,
1-1. 그런 이미지들 중 일단 하나를 선택한다.
2. 그 한 이미지의 사이즈를 알아낸다.
3. 이미지의 폭이 기준(640)보다 큰가 작은가
3-1. 작다면 그냥 내버려둔다. 더 할게 없다. 일단 이 이미지에 대해서는 끝.
3-2. 크다면, 그게 넓쭉한가 길쭉한가?
3-2-1. 넓쭉하다면, 그것의 크기는 640x480이 되어야 한다.
3-2-2. 길쭉하다면, 폭은 640이고,
  길이는 원래 길이가 A, 폭이 B 였다면, A : B = 새 길이 : 640 이 되어야 하니깐, 새 길이는 ( A 곱하기 640 ) 나누기 B이다.
4. 이 이미지의 크기를 계산한대로 조정한다. 이 이미지에 대해서 더 할게 없다. 끝.
5. 이제 이 이미지는 됐다. 다음 이미지를 불러오자. 1-1로 다시 간다.

쓰고 보니 그렇게 쉬운 예를 고른 건 아니라는 생각이 든다. 벌써 이 블로그를 떠나려는 마우스의 움직임이 그려진다.
잘못했어요. 미안. 가지 마세요 -_-


어쨌든 프로그램을 짠다는 것은 이렇게 컴퓨터의 동작 방식을 이해하고, 내가 원하는 작업이 실제로 어떤 세부적인 과정을 통해 이뤄지는지 파악한 다음, 그걸 컴퓨터가 알아들을 수 있는 언어로 번역해주는 작업이다.
지금까지 한 것이 바로 "사람이 이해할 수 있는 수준에서 작업을 세부 과정으로 쪼갠" 것이다.

하지만 모든 프로그램이 사실 이렇게 만들어지진 않는다. 아주 간단한 프로그램의 경우는, 무작정 컴퓨터와 직접 소통을 시도하며 쉬운 것부터 시키고, 점차 조금씩 많은 걸 시켜가면서 내가 원하는 것이 점점 반영되도록 계속 수정해서 만들기도 한다. 예를 들면, 일단 스크립트 파일을 하나 만들어 놓고, 거기에 한 두줄만 써넣는다. 내 욕망을 한번에 다 쏟아내는게 아니라 작은 것부터 하나씩 점차 이뤄지도록 한다. 단순한 작업을 하는 스크립트에서 출발해 점점 많은 일을 하고, 많은 것을 고려하는 똑똑한 스크립트로 발전시켜나가는 것이다.

일단 내가 처할 상황을 단순화한다. 보통 내가 디카로 사진을 찍을때 1600 x 1200 이상으로 찍으니 길쭉 넓쭉한 건 있어도 어쨌든 640x480보단 다 클것이다. 다른 경우에 쓸 일이 있으나 일단은 이런 경우를 가정한다. 그리고 이미지는 JPG, GIF등은 말고, PNG만 고치기로 한다.

먼저, 디렉토리를 따로 만들어 길쭉한 사진은 빼놓고(수동), 스크립트가 다음 작업만 하게 한다.
1. 내가 지정하는 이미지들이 어떤 것인지 알아차리고,
2. 다음 과정을 반복한다.
  - 이미지를 하나씩 선택한다. 모두 처리했다면 반복을 끝낸다.
  - 선택한 이미지의 크기를 640x480으로 조정한다.

코드로 옮겨본다. (일단은 그냥 편하게 보자) 파일 이름은 img_resize 정도로 하자. 그냥 텍스트 파일로 만들면 된다. 실행방법은 나중에.

#! /bin/bash
convert -resize 640x480 *.png

이렇게 한(두)줄 스크립트도 충분히 우리를 행복하게 할 수 있는데, "지금 디렉토리의 모든 PNG파일을 640x480크기로 바꿔라"는 말을 "convert -resize 640x480 *.png"라고 타이핑하다가, 이제는 "img_resize"라고 10글자만 타이핑해도 되니까. 스크립트가 별개 아니다. 평소에 복잡하고 긴 명령어를 매번 타이핑해주고 있다면 그냥 이렇게 텍스트 파일에 써놓고 앞으로 그 파일 이름만 타이핑하자. 그것만으로도 우리의 스트레스는 급감한다. 타이핑 양도 줄고, 오타도 줄고, 신경쓸 일도 준다.


이것과 정확히 같은 역할을 하는 코드인데, 앞으로를 위해 "반복 제어문"을 넣은 형태로 바꾸자.

#! /bin/bash
모든 PNG파일중 하나씩 선택해서
   convert -resize 640x480 선택한파일
한다.

컴퓨터가 알아들을 수 있게 바꾸면,

#! /bin/bash
for img in *.png
do
    convert -resize 640x480 $img
done

그냥, for... 문이 반복문인데, 반복할 명령어를 do ~ done 으로 묶어주는구나. 정도 이해해주고 패스.


그래놓고, 이게 잘 되면 조금씩 기능을 추가해간다.
1. 내가 지정하는 이미지들이 어떤 것인지 따로 적어놓고,
2. 다음 과정을 반복한다.
  - 처리 안한 이미지를 하나 선택한다. 모두 처리했다면 반복을 끝낸다.
  * 이미지 폭이 640 보다 큰지 작은지 판단한다.
  **  작으면, 할게 없다.
  **  크면, 선택한 이미지의 크기를 640x480으로 조정한다.


자, 코드는 아래처럼 변해야 한다.

#! /bin/bash
for img in *.png
do
    이미지 폭을 계산한다.
    이미지 폭이 640보다 크면,
         convert -resize 640x480 *.png
    한다
done

자, 사람의 말을 컴퓨터의 말로 바꾸자.
여기서는 아래 코드를 복사&붙여넣기(Copy&Paste)하기로 한다. 골치아프니 일단 생각하지 말고.
  imgwidth=`identify -ping $img | cut -f 3 -d " " | cut -f 1 -d "x"`

#! /bin/bash
for img in *.png
do
    imgwidth=`identify -ping $img | cut -f 3 -d " " | cut -f 1 -d "x"`
    이미지 폭이 640보다 크면
         convert -resize 640x480 *.png
    한다.
done

나머지 부분도 바꿔보자. bash 쉘(리눅스에서 기본으로 사용하는 CUI) 스크립트에서 판단은 if... 를 사용한다.

if [ 조건 ]; then
   할일.
fi

이래놓으면, "조건"이 참일때 "할일"을 수행한다. 본래 코드에 적용

#! /bin/bash
for img in *.png
do
    imgwidth=`identify -ping $img | cut -f 3 -d " " | cut -f 1 -d "x"`
    if [ 이미지 폭이 640보다 크다 ]; then
         convert -resize 640x480 *.png
    fi
done

이젠, 조건에 해당하는 부분을 컴퓨터말로 바꾸자. "~보다 크다"는 "-gt"를 사용한다.
이미지폭은 바로 윗줄에서 계산해서 imgwidth 라는 곳에 값을 적어놨다. "$"를 붙여 $imgwidth 라고 하면 거기에 적힌 값을 사용할 수 있다.
=> $imgwidth -gt 640

#! /bin/bash
for img in *.png
do
    imgwidth=`identify -ping $img | cut -f 3 -d " " | cut -f 1 -d "x"`
    if [ $imgwidth -gt 640 ]; then
         convert -resize 640x480 *.png
    fi
done

여기까지 잘 되면, 또 기능을 추가한다. To be continue...
진보블로그 공감 버튼트위터로 리트윗하기페이스북에 공유하기딜리셔스에 북마크
2007/07/13 20:50 2007/07/13 20:50
Trackback Address :: http://blog.jinbo.net/h2dj/trackback/476
Tracked from | 2007/07/13 22:13 | DEL
자, 2편에서 우리는 img_resize 라는 스크립트를 만들었다. 이걸 좀 더 우리의 욕망을 충실히 담도록 진보시키자. 하지만 그전에, 도대체 우리가 뭘 하고 있는지 실제로 확인해야 좀 더 신이 날 것 같다. 저렇게 만든 스크립트를 어떻게 실행하고, 활용할지 보자. 우선, 리눅스는 보안을 위해 적절한 권한이 없으면 말을 안듣는다. img_resize 가 실행하려면 먼저 이 파일에 "실행권한"을 줘야 한다. 그냥 여기서 이해하던 못하던
su 2007/07/15 19:01 URL EDIT REPLY
안녕하세요. 올블타고 왔어요. 히히,
지각생 2007/07/16 13:01 URL EDIT REPLY
어라? 추천받았네 ^^;;
Name
Password
Homepage
Secret