[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]


사용한 품목


1) 라즈베리파이B+ 베이직 키트: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005607887&LType=R


들어가면서


    오랜만에 쓰는 포스팅이다. 텔레그램 봇을 만드려는 이유는 키워드를 이용하여 검색을 쉽게 할 수 있도록 하기 위함이었다. 하지만 '에버노트'에서 키워드와 같은 태그 기능을 제공했다. 역시 내가 한 생각을 보다 더 빨리 하는 사람이 있다. 이런저런 머리에 떠다니는 생각은 많지만 제대로 정리가 되지 않아서 골치아픈 것을 해결하고자 텔레그램 봇을 만들려고 했는데 에버노트에 있는 것을 보고 좌절했다. 그래서 나도 에버노트를 사용하기로 했고, 잘 사용하고 있다 ^오^

     그래서 다른 내용에 포스팅을 하려고 하는데 docker가 최근에 부각되고 있는 것을 알 수 있었다. 그래서 이번 기회에 라즈베리파이에서 docker 이용에 대해 알아보려고 한다. docker의 가벼움과 확장성이 라즈베리파이와 잘 어울려 질 것 같다.


docker


    먼저, 도커의 정의에 대해 알아보도록 하자. 도커의 공식 홈페이지는 도커를 아래와 같이 정의하고 있다.

Docker allows you to package an application with all of its dependencies into a standardized unit for software development.

-https://www.docker.com/what-docker

     약간 의역하자면 "프로그램 개발할 때 필요한 라이브러리들까지 포함된 패키지"라고 생각하면 된다. 소프트웨어 개발을 하거나 실험하는 경우에 테스트 환경을 구축해야 되는 경우가 있다. 특히, 새로운 환경에서 테스트를 하려고 할 때 테스트 프로그램을 설치뿐만 아니라 테스트 프로그램이 필요로 하는 프로그램도 함께 설치해줘야 한다는 문제를 가지고 있다. 이를 docker는 쉽게 해결해줬다. 

     또, docker는 가상머신과 비슷한 구석이 있지만 더욱 가벼운 놈이라고 보면 되겠다. 아래 그림은 docker공식 홈페이지에서 그림으로 표현한 것이다. 일반적인 가상머신은 Host OS 위에 hypervier위에 Guest OS위에 프로그램을 설치해야 한다. ('위'라는 단어가 3번 나왔다) 하지만 docker의 콘테이너를 이용하면 Host OS위에 도커엔진 위에 바로 여러 프로그램들을 설치할 수 있다. 뿐만 아니라 앞서 언급한 것처럼 프로그램 동작에 필요한 관련 프로그램도 함께 설치해준다. 

     하이퍼바이저와 가장 큰 차이점은 하이퍼바이저는 여러 OS를 사용할 수 있지만, 도커는 불가능하다. 하지만 도커는 여러 소프트웨어의 버전을 다르게 설치하고 운영할 수 있는 장점을 가지고 있다. 이를 하이퍼바이저에서 사용하려면 많은 저장공간의 낭비가 된다. 도커에 대한 설명은 여기까지 하는 걸로 하겠다. 아래 3개의 글을 참고했다.

http://bcho.tistory.com/805

http://www.zdnet.co.kr/news/news_view.asp?artice_id=20140812121328

http://www.itworld.co.kr/news/87971

마지막으로 "가장 빨리 만나는 docker"를 쓰신 작가님의 홈페이지에서 관련 정보를 얻는 것이 더욱 효과적일 것 같다.

http://pyrasis.com/docker.html


라즈비안에서의 docker 설치


    이제 본격적으로 라즈베리파이에서 docker설치에 대해 알아보도록 하자. 더욱 좁혀 라즈비안을 설치한 라즈베리파이에서 docker의 설치에 대해 알아본다. 검색을 하다보니 arch linux에서 docker 설치에 대한 글을 쉽게 접할 수 있었지만 라즈비안에 대한 글은 흔하지 않을 것을 알 수 있었다. 라즈베리파이에서의 docker설치에 대한 글을 한참 보다가 arch linux에서 설치인 것을 깨닫고 헛탕을 몇번 쳤다.

     라즈비안에서 docker설치는 크게 2가지로 나눌 수 있다.

  1. docker가 설치된 라즈비안 이미지 설치

  2. 라즈비안에 직접 docker설치


 쉬운 길 놔두고 돌아가랴!, 직접 docker를 설치하는 것보다 기존에 있는 이미지를 설치하기로 했다. docker가 설치된 라즈비안 이미지는 아래 링크에서 받을 수 있다. 이 이미지를 win32 Disk Imager로 sd카드에 쓰면 된다. 하지만 이는 해당 이미지를 제공하는 측에서 어떤 프로그램을 더 설치했을 지 모르고, 무엇보다 ipv6가 기본으로 잡혀져 있다. 

http://blog.hypriot.com/post/heavily-armed-after-major-upgrade-raspberry-pi-with-docker-1-dot-5-0/

     docker가 설치되어 있는 라즈비안 이미지라고 하더라도 docker 이미지(프로그램)을 받을 수가 없다면 말짱 도루묵이다. 또, 필자는 ipv4를 써야만 하는 환경에 있을 뿐더러 ipv6의 경험이 없다. 그래서 ipv6을 해제하고 ipv4 변경하려고 했는데 몇번의 실패가 있었다. 또한, 처음 라즈비안을 설치할 때 했던 설정들이 이 이미지에는 없다. 그래서 한글 키보드나 시간 등 관련설정들을 못해준다.  아래 그림과 같이 인터넷이 되질 않는다.


▲흑흑.. 왜 핑이 안되니

     그래서 차선책으로 다시 라즈비안 이미지를 설치하고 관련 설정들을 모두 해준 후 차례대로 docker를 설치해보려고 한다. 먼저 이런 문제들을 겪으면서 한글 키보드나 한글 설정이 필요없으며, ipv6로 사용 가능한 사람은 docker가 설치된 이미지를 다운 받아 설치하면 상관없겠지만 그렇지 않다면 차례대로 설치하도록 하자.

마치면서


    docker에 대해 간단하게 이야기하고 docker를 라즈비안에 설치하기 위한 방법에 대해 알아봤다. 그 중 이미지를 이용한 방법을 통해서는 ipv6의 문제와 같은 여러 설정문제가 존재한다는 것을 알았다. 몇 시간의 삽질을 통해 해결하려고 했지만 실패했고, 이에 차선책으로 넘어가고자 한다.

관련 상품


라즈베리파이2 보드: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005652343

라즈베리파이2 베이직 키트: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005655515

손톱두이노: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005668577

라즈베리파이 전용 방열판 (소): 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P002110427


[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]







  1. 1466258358 2016.06.18 22:59 신고

    좋은글 감사



linux z3 install

32bit

http://daehee87.tistory.com/460

64bit

http://smleenull.tistory.com/591


http://research.microsoft.com/en-us/um/redmond/projects/z3/Z3_System.pdf


z3 사용법

http://cpl0.net/~argp/papers/z3py-guide.pdf

http://xer0s.tistory.com/97

http://flack3r.tistory.com/110

[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]





사용한 품목


1) 라즈베리파이B+ 베이직 키트: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005607887&LType=R


들어가면서


 지난 포스팅까지는 텔레그램 CLI를 이용하기 위해 사용하는 lua와 sqlite3의 연동하는 방법과 간단한 코드를 봤다. 이제는 메세지를 받아서 어떤 메시지인지 확인하여 삽입(insert), 삭제(delete), 검색(select)하는 것에 대하 포스팅 하도록 하겠다. 

lua 문자열 처리



  특정 언어로 데이터베이스와 연동하기 위해서는 해당 언어의 문자열 처리방식에 대해 알아야 한다. 각 언어마다 문자열 처리 방식이 다르므로 lua의 문자열 방식에 대해 간단하게 알아보고 넘어가도록 하겠다. 아래 URL을 참고해도 좋다. 

http://lua-users.org/wiki/PatternsTutorial

http://namirde.blogspot.kr/2010/04/p11.html

http://lua-users.org/wiki/StringLibraryTutorial

일반적으로 문자열을 더하기 위해서 lua에서는 '..''+' 을 사용한다. 간단한 예이다.

a= 'world'

"hello"..a or "hello" + a    

 ==> "hello world"가 된다.

 

 데이터베이스의 데이터를 받아왔을 때 문자열인 경우도 있지만 숫자인 경우도 있다. 그러므로 문자열로 처리하기 위해서는 숫자를 문자열로 만들어주는 기능이 필요하다.

str = tostring("123")

 위에서도 언급했듯이 텔레그램 봇은 삽입, 검색, 삭제 기능이 있다. 그러므로 각 명령어를 받아서 쉘처럼 각 기능을 처리해야 한다. 텔레그램 자체는 문자열을 받는 것이므로 이 문자열을 잘라서 어떤 문자인지 판단해야 한다. 그러므로 문자열 자르는 기능, 특정 문자열을 찾는 기능, 문자열의 길이를 확인하는 기능이 필요하다.

string.sub(문자열, 시작 위치, 끝 위치)

  • 문자열에서 시작위치와 끝위치까지 자른다.

string.len(문자열)

  • 문자열의 길이를 구한다.

string.find(문자열, 찾는 문자열)

  • 문자열에서 찾는 문자열 찾아서 위치를 반환한다.


lua와 sqlite3을 연동한 텔레그램 메모 만들기


 이제 관련 문자열 만드는 것도 다 처리했으니 아래에 소스를 첨부한다. 그냥 빠르게 짜기 위해서 문자열 길이를 받고 자르고 해서 그렇게 좋은 효율을 가지는 코드는 아니다. 또한 나는 개발자가 아니므로 좋은 코드를 만드는 것보다 빠르게 코드를 만드는 것에 의의를 뒀다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
sqlite3 = require("lsqlite3")
db = sqlite3.open('memo.db')
function on_msg_receive(msg)
    memo_help_msg = "메모 [내용] [키워드]"
    no_msg = "[*] 번호 [*]\n"
    time_msg ="\n[*] 시간 [*]\n"
    content_msg = "\n[*] 내용 [*]\n"
    keyword_msg = "\n[*] 키워드 [*]\n"
    local m_msg = string.lower(msg.text) 
    local start_s, end_s = string.find(m_msg, "검색")
    local start_m, end_m = string.find(m_msg, "메모")
    local start_d, end_d = string.find(m_msg, "삭제")
    if(string.lower(msg.text)=="hello")then
        mark_read(msg.from.print_name, ok_cb, false)
        send_msg(msg.from.print_name, "world", oc_cb,false)
    elseif(msg.text=="올ㅋ")then
        mark_read(msg.from.print_name, ok_cb, false)
        local regdate = ""
        local content = ""
        local keyword = ""
        for row in db:nrows("SELECT * FROM test"do
            regdate = tostring(row.regdate)
          content = tostring(row.content)
          keyword = tostring(row.keyword)
          message = string.format("%s%s%s%s%s%s",time_msg,regdate,content_msg,content,keyword_msg,keyword)
                  send_msg(msg.from.print_name, message, oc_cb,false)
        end
    elseif(start_s == 1 and end_s == 6) then
        mark_read(msg.from.print_name, ok_ck, false)
        default_query = "SELECT * FROM test "
        start_c, end_c = string.find(m_msg,"내용")
        start_k, end_k = string.find(m_msg,"키워드")
        start_t, end_t = string.find(m_msg,"시간")
        if( start_c == 8 and end_c == 13)then
            content_query = "where content like '%"
            content_to_find = string.sub(m_msg,15,string.len(m_msg))
            end_query = "%'"
            final_query = string.format("%s%s%s%s",default_query,content_query,content_to_find,end_query)
            for row in db:nrows(final_query) do
             no = tostring(row.id)
               regdate = tostring(row.regdate)
             content = tostring(row.content)
             keyword = tostring(row.keyword)
             message = string.format("%s%s%s%s%s%s%s%s",no_msg,no,time_msg,regdate,content_msg,content,keyword_msg,keyword)
                        send_msg(msg.from.print_name, message, oc_cb,false)
            end
        elseif( start_k == 8 and end_k == 16)then
            keyword_query = "where keyword like '%"
            keyword_to_find = string.sub(m_msg,18,string.len(m_msg))
            end_query = "%'"
            final_query = string.format("%s%s%s%s",default_query,keyword_query,keyword_to_find,end_query)
            for row in db:nrows(final_query) do
             no = tostring(row.id)
               regdate = tostring(row.regdate)
             content = tostring(row.content)
             keyword = tostring(row.keyword)
             message = string.format("%s%s%s%s%s%s%s%s",no_msg,no,time_msg,regdate,content_msg,content,keyword_msg,keyword)
 
             send_msg(msg.from.print_name,message,oc_cb,false)
            end
        elseif( start_t == 8 and end_t == 13)then
            send_msg(msg.from.print_name,v,oc_cb,false)
        end
    elseif(start_m == 1 and end_m == 6)then
        save_message = "\n[*] 저장 완료 [*]"
        start_memo, end_memo = string.find(m_msg,"메모%s+")
        start_memo, end_content = string.find(m_msg,"메.*%s")
        insert_content = string.sub(m_msg,end_memo+1,end_content-1)
        insert_keyword = string.sub(m_msg,end_content+1,string.len(m_msg))
        local tablefill = [[INSERT INTO test VALUES (NULL, datetime('now','localtime'),']]..insert_content..[[',']].. insert_keyword..[[');]]
        db:exec(tablefill)
        send_msg(msg.from.print_name,"[*] 내용\t:\t"..insert_content.."\n[*] 키워드\t:\t"..insert_keyword..save_message,oc_cb,false)
    elseif(start_d == 1 and end_d == 6)then
        save_message = "\n[*] 삭제 완료 [*]\n"
        start_memo, end_memo = string.find(m_msg,"삭제%s+")
        delete_id = string.sub(m_msg,end_memo+1,string.len(m_msg))    
        send_msg(msg.from.print_name,delete_id,oc_cb,false)
        local deletefill = [[DELETE FROM test where id =']]..delete_id..[[';]]
        db:exec(deletefill)
        send_msg(msg.from.print_name,save_message,oc_cb,false)
    end
end
function ok_cb(extra, succes,result)
end
cs

 

     명령어는 문자열에서 특정 문자(검색, 삭제, 메모)의 위치가 어디인지 판단하여 시작위치가 1이고 끝나는 위치가 6이면 문자열의 첫 두글자에 내가 찾는 문자가 있다는 것을 의미한다. 재밌게도 lua에서는 한글 한글자를 3바이트로 인식하는 것을 알 수 있었다.  

     예를 보도록 하자. 아래 그림과 같이 a라는 변수에 "테스트"를 넣고 string.find함수로 문자열의 위치를 찾았다. 아래 보는 것과 같이 "테"의 시작 위치가 1이고 끝나는 위치가 3이다. 응? 한글이 2바이트 인 것을 고려하면 시작위치가 1이고 끝나는 위치가 2이여야 하는데 3이다. 뭔가 다른게 잘못되어 그렇다고 볼 수 있는데 "스"와 "트"의 경우를 봐도 3바이트 인 것을 알 수 있다.


그래서 2글자로 이루어진 명령어(검색, 메모, 삭제)를 이용하기 때문에 그 string.find를 이용하여 해당 글자의 시작이 1이고 끝이 6인 것을 판단해야 한다. 하지만 '올ㅋ'는 그냥 문자열 비교를 했다. 그 이유는 올ㅋ의 경우 모든 리스트를 출력하는 것이기 때문에 추가적인 인자(정보)가 필요없다. 하지만 다른 명령의 경우는 메모를 하기 위해서는 [내용], [키워드]가 필요하고, 검색을 위해서도 어떤 종류(내용, 키워드)를 볼 지, 그 내용이 어떤 것인지 알아야 한다. 그러므로 검색이나 메모를 하기 위해서 앞 2글자가 검색, 메모, 삭제인 경우 뒤쪽의 인자들을 잘라서 처리해야 한다.

     이를 위해 아래와 같이 66, 67줄에 있는 string.find 명령어를 특정문자와 결합하여 정규표현식처럼 사용할 수 있다. 그러면 명령어의 포맷은 [명령종류][공백][인자1][공백][인자2]에서 명령어의 종류와 인자 1과 인자 2를 잘라서 가져올 수 있다.

        start_memo, end_memo = string.find(m_msg,"메모%s+")
        start_memo, end_content = string.find(m_msg,"메.*%s")

     그래서 아래와 같이 메모[공백]테스트1[공백]테스트2로 입력을 받는다. 그래서 이 명령을 받은 프로그램은 아! 지금 메모를 하고 내용으로는 테스트1, 키워드로는 테스트2를 넣구나라는 것을 알 수 있다. 




     이번은 검색[공백]키워드[공백]테스트2를 받는다. 이를 받으면 텔레그램 봇은 "아! 키워드에 테스트2라는 단어가 포함된 메모를 검색하라는 거구나!"라고 판단한다. 여기서 나타나는 시간은 메모를 저장했을 때 당시의 시간을 입력한 것이다. 


     여기서 나타나는 시간은 메모를 저장했을 때 당시의 시간을 입력한 것이다. 그래야 내가 어떤 시점에 이런 메모를 썼다는 것을 알 수가 있고, 비슷한 메모를 구분 할 수 있는 근거가 된다고 생각한다. sqlite3의 테이블은 id, regtime, content, keyword로 나뉘어져 있다. id는 각 메모를 구분하기 위한 숫자이고, regtime은 메모를 저장할 당시의 시간, content는 내용, keyword는 내용을 구분할 수 있는 핵심 단어나 카테고리로 추후에 검색할 때 유용하게 사용할 수 있는 부분이라고 할 수 있다.

     아래 사진은 텔레그램 웹버전으로 명령을 내린 것이다. [*]으로 봇이 보내준 것인지 내가 내린 명령인지 쉽게 판단할 수 있을 거라 생각한다. 







마치면서


     이번 포스팅을 마치면서 lua와 sqlit를 연동하는데 어려움을 겪었다. 특히 아래처럼 특정 문자열은 정적으로 들어가고 특정 문자열을 동적으로 들어가는데 이를 합쳐서 db에 요청하는 것이 헷갈렸다.

"[*] 내용\t:\t"..insert_content.."\n[*] 키워드\t:\t"..insert_keyword..save_message

 sqlite3를 코딩하는 것도 lua를 코딩하는 것도 이번 텔레그램 봇을 만들면서 쓰는 것이 처음이라 더욱 생소했다. 하지만 이번 기회를 통해 특정언어를 사용하기 위해 먼저 데이터 형식에 대해 가장 먼저 알아봐야 한다는 사실을 알 수 있었다. 각 언어마다 데이터 형식과 처리방식이 다르기 때문이다. 이번 달에 포스팅은 이걸로 마치고 다음 포스팅에서는 궁극적으로 원했던 "짤방저장소"를 만들어 보도록 하겠다.

관련 상품


라즈베리파이2 보드: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005652343

라즈베리파이2 베이직 키트: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005655515

손톱두이노: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005668577

라즈베리파이 전용 방열판 (소): 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P002110427





[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]



  1. urxtion 2015.09.01 10:39 신고

    짤방저장소 빨리 해보고싶네요 ㅠㅠ!!
    기대하겠습니다!!!!

  2. urxtion 2015.09.01 10:39 신고

    짤방저장소 빨리 해보고싶네요 ㅠㅠ!!
    기대하겠습니다!!!!

  3. urxtion 2015.09.01 10:39 신고

    짤방저장소 빨리 해보고싶네요 ㅠㅠ!!
    기대하겠습니다!!!!

[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]




사용한 품목


1) 라즈베리파이B+ 베이직 키트: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005607887&LType=R


들어가면서


 지난 포스팅까지는 간단한 텔레그램 CLI를 이용하여 간단한 봇을 만들어봤다. 이제는 텔레그램을 이용한 메모장을 만들어보려한다. 나처럼 여러 장소에 메모를 적어서 관리를 잘 못하는 사람에게 도움이 될 거라 생각한다. 그리고 텔레그램 CLI의 사진 보내기 기능을 함께 쓰면 짤방저장소로 사용할 수 있어서 재밌을 것 같다.

luarocks



  lua에서 사용하는 module들을 관리하기 위해서 사용하는 패키지가 luarocks다. 리눅스 환경에서 apt-get install과 같은 느낌을 받았다. 그러므로 쉽게 설치하기 위해 luaroacks를 설치하도록 하자. 공식 홈페이지는 아래와 같다.

https://luarocks.org

 아래와 같은 순서대로 luarocks를 설치하도록 하자. 복사 하기 쉽도록 아래와 같이 명령어를 놔뒀다.

1
2
3
4
5
wget http://luarocks.org/releases/luarocks-2.2.2.tar.gz
tar zxpf luarocks-2.2.2.tar.gz
cd luarocks-2.2.2
./configure; sudo make bootstrap
sudo luarocks install luasocket
cs


아래 사진은 직접 위의 명령어를 입력하면서 나오는 결과를 함께 보여준다. 익숙하지 않는 환경을 설치하는 데 도움을 줄 수 있을 거라 믿는다.



그 다음에는 lua와 sqlite와 연동하는데 필요한 프로그램을 apt-get install로 하나, luarocks로 2개를 설치한다. 솔직히 이 중에서 어떤 것이 정말 필요한 것이고 쓸모 없는 것인지 판단이 안서지만, 모두 설치해서 환경설정에 관한 스트레스를 받지 않도록 하자.

1
2
3
apt-get install libsqlite3-dev
luarocks install luasql-sqlite3
luarocks  install lsqlite3 
cs





lsqlite3 사용, 그리고 기본적 문법


 관련 모듈을 설치했으면 이제 직접 lua와 sqlite3을 연동하도록 하자. 먼저 lua와 sqlite3를 연동하는 것을 성공하고 난 뒤에 텔레그램 CLI에 붙이도록 하자. 바로 소스에 넣으려고 했다가 문제가 발생할 수 있으니 하나하나 만들고 붙이는 방법을 택하여 알 수 없는 오류에 처하는 상황을 최대한 줄인다.

아래 코드와 같은 소스를 하나 만든다. 간단하게 설명하도록 하겠다.

sqlite3 = require("lsqlite3")

    • lsqlite3모듈을 불러와서 해당 인스턴스를 sqlite3에 저장한다.

local db = sqlite3.open('test3.db")

    • sqlite3는 test3.db라는 파일을 불러와서 연결 인스턴스를 db라는 변수에 저장한다.

db:exec[[

CREATE TABLE test(id, content);

INSERT INTO test VALUES (1, "Hello World');

INSERT INTO test VALUES (2, "Hello world');

]]

      • id와 content 라는 이름의 열을 가진 test 테이블을 만들고 더미 값 2개를 넣는다.


for row in db:nrows("SELECT * FROM test") do

    print(row.id, row.content)

end

      • select * from test쿼리를 이용하여 [1, hello world], [2, hello world]를 출력한다.

db:close() 

      • 데이터베이스 연결을 끊는다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sqlite3 = require("lsqlite3")
local db = sqlite3.open('test3.db')
 
db:exec[[
  CREATE TABLE test(id, content);
  INSERT INTO test VALUES (1'Hello World');
  INSERT INTO test VALUES (2'Hello World');
]]
 
for row in db:nrows("SELECT * FROM test"do
  print(row.id, row.content)
end
 
db:close()
cs


 위 코드를 만들고 lua 파일명.lua를 실행하면 아래와 같은 결과가 나온다. 이는 test3.db에 테이블을 만들고 데이터를 입력하고 출력하는 작업을 보여준다. 





마치면서


 이번 포스팅에서 텔레그램 CLI와 sqlite3을 연동하기 위한 방법을 봤다. 텔레그램 CLI는 lua로 이루어져 있으므로 lua와 sqlite3 연동하기 위해 모듈을 쉽게 설치하도록 도와주는 luarocks를 설치했다. 이를 이용하여 설치 완료했고 간단하게 lua와 sqlite3를 연동하는 코드를 봤다. 다음 포스팅에서는 본격적으로 텔레그램에서 메시지를 받아서 sqlite3에 데이터를 넣고(insert) 빼고(delete) 보여주는(select)하는 것에 대해 알아보도록 하겠다.

관련 상품


라즈베리파이2 보드: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005652343

라즈베리파이2 베이직 키트: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005655515

손톱두이노: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005668577

라즈베리파이 전용 방열판 (소): 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P002110427





[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]





들어가면서


     이 책은 마이크로소프트에 있던 존 우드가 휴가로 간 네팔의 열악한 교육환경에 대해 게 된 에 사직을 하고 '룸 투 리드'라는 단체를 만든 것에 대한 내용이다.'열혈교사 도전기'와 마찬가지로 열악한 교육환경을 개선하기 위해 열심히 뛴 사람과 결과에 대한 내용이다.

기억에 남는 것


이 책을 읽으며 내 머리를 강타한 것이 베트남 청년 '부'에 대한 내용이다. 힘든 환경에서도 불구하고 하루에 4시간을 자며, 컴퓨터와 공부에 대한 강한 열정으로 하루를 살아가고 있다. 가족을 돌보기 위해, 생계를 이어 나가기 위해 하는 일을 하고 남는 자투리 시간을 활용하여 공부하는 그의 모습이 감탄했다. 그리고 상대적으로 몹시 풍족한 삶을 사는 내가 공부하는 것에 대한 즐거움과 감사함을 가지지 못한 것이 부끄러웠다. 또, 군 복무 때 컴퓨터에 관한 것이면 적극적으로 배우고 공부했던 내 모습이 사라져서 다시 한번 더 부끄러웠다. 이 부끄러움을 오늘 꼭 이 책을 다 읽고 말리라는 결심으로 바꼈고, 그래서 지금 이렇게 서평을 쓴다ㅎㅎ.

세상에는 태어나는 지역, 나라에 따라 자신의 의지와 상관없이 열악한 교육환경에 처한다. 우리나라 주변에는 책이 주변에 충분히 많지만, 네팔에는 학교 도서관에 책이 한 권도 없던 곳도 있었다. 이런 안타까움이 존 우드를 '룸 투 리드'를 만들도록 했고, 그 스스로 만족하는 삶을 살도록 했다. 그의 엄청난 열정이 네팔을 넘어 인도, 캄보니아, 스리랑카 등에도 전해지는 것을 보고 다시 한번 감명받았다. 아래에 기억에 남는 책의 구절을 따로 적어 둘 것이지만 그가 스스로 만족하고 있다는 사실을 극명하게 보여주는 구절이다. 학교가 완공되고 리본을 자르는 장면에서 그는 '이 순간을 영원히 간직하고 싶었다'라고 했다. 정말 자신이 하는 일에 보람을 느끼고 열정을 가진 사람이라고 생각한다.

아래에는 내가 책을 읽으며 좋은 느낌을 받았던 구절에 대해 정리했다.

  • P175 개인을 공격할 순 없지만 생각을 공격할 수 있다.
  • P183 직원들에 대한 나의 관심을 드러내는 방법은 성실과 정직이다. 룸투리드를 위해 그들이 봉사하고 있음을 나는 안다. 그리고 나는 그들을 믿는다.
  • P195 실천할 수 없다고 말하는 사람은 실천하고 있는 사람을 비난해서는 안된다.
  • P245 과거를 바꿀 수는 없지만 미래를 바꿀 수 있다고 굳게 믿는다. 앉아서 도우려 하지 않고, 움직이고 행동한다. 

마치면서


     내게 주어진 상황이 너무 과분하다는 것을 이 책을 통해 알게 됬다. 그리고 나 스스로 적극적으로 공부하면서 그 상황에 몰입하기 위해서 다시 한번 나를 채찍질하는 계기를 가졌다. 재밌는 것은 결국 생각이나 말보다 행동이 먼저라는 것이다. 생각이나 말을 통해 합리화를 하거나 변명을 대면서 행동을 유예하고 주저하게 만들기 때문이다. 또 책을 읽으면서 개인적으로 존 우드의 글 솜씨에 놀랐다. 디테일한 상황묘사와 묘하게 내 마음을 끌어 당기는 글 덕분에 재밌게 읽었다. 



들어가면서


     이 책은 "TFA(Teach For America)"으로 저소득 계층의 아이들에게 부유한 계층의 아이와 동등한 교육을 제공하기 위한 비전을 가진 단체에 대한 내용이다. 저자는 핸디 콥으로  '저소득 지역 학생들을 돕기 위한  교사 양성 양성 봉사조직에 대한 고찰'이라는 졸업논문을 쓰고 이를 실천하면서 겪는 이야기에 대한 내용이다.

기억에 남는 것들


     TFA라는 단체를 운영하면서 생기는 우여곡절이 창업의 과정과 같아서 내게 재밌게 다가왔다. 물론 TFA는 비영리단체므로 창업과 약간의 차이는 있지만 인간관계에서 나오는 문제들과 처음에 생각하지도 못했던 문제들이 생기는 것이 재밌었다. 특히 TFA의 스태프들에게 월급을 주지 못할 지도 모른다는 두려움에 대한 스트레스를 잠에서 깨자마자 하는 저자의 모습이 중소기업의 리더가 가질만 한 스트레스라고 생각했다. 예전에 창업관련 세미나를 들을 때 어떤 중소기업의 CEO분이 "한달마다 월급 날에 급여를 주지 못할 지도 모른다는 스트레스를 계속 받는다'는 말과 비슷해서 더욱 와 닿았다. 

     조직의 수평적인 구조를 지향했었는데, TFA에 겪은 문제를 보고 다시 한번 생각 해보게 됬다. 그리고 이를 해결하기 위해 닉 그로버로 부터 받는 조직의 균형, 영역별 리더의 존재, 의사결정 과정의 명확화라는 3가지 방법에 대해서도 생각했다. 아직은 정확하게는 모르겠지만 천천히 이에 대해 계속 고민 해 볼 필요가 있다. 유보하지만 잊지 않고 유념할 부분이다. 

     TFA의 성공적인 교사들의 교육법에 대해서 생각했다. 분명한 목표를 세우고 이를 실천하기 위해 시간을 투자하도록 한다. 그리고 아이들 뿐만 아니라 부모님과도 함께 하면서 친밀한 관계가 된다. 그렇게 해서 열심히하면 이룰 수 있다는 확신을 심어준다. 또 대학생이나 취업한 사람을 만나도록 하여 아이들의 역학모델을 세우고 자신도 그렇게 될 수 있다는 믿음도 준다. 요즘들어 생각하는 '우선순위의 문제'와 '스스로 이뤄낼 수 있다는 믿음'에 대한 생각과 맞 닿아 있다. 구체적으로 학생들에게 해 줄 수 있는 부분이라고 생각한다. 어떤 목표를 성취한 경험이 다음의 목표를 나아갈 때 좋은 영향을 아이들에게 줄 수 있을 거라 믿는다.

마치면서


     이제는 서평을 쓰는데 많은 부담을 느끼지 않기로 했다. 먼저 들어가면서에서는 이 책에 대한 간단한 내용과 워밍업, 책 제목을 보고 느꼈던 내 생각에 대해 적을 것이다. 그리고 본문에는 책을 읽으며 들었던 내 생각과 기억에 남는 내용을 위주로 정리하고, 마치면서에서는 앞으로 생각 해 볼 이야기나 느낌에 대해 적도록 할 것이다. 

     일단 재밌는 것은 사람들이 모이게 되면 문제가 생길 수 밖에 없다는 사실에 씁쓸했다. 비영리단체가 자금적인 지원을 받는 것에 대해 알게 되어 신기했고, 우리나라에 있는 비영리단체도 TFA와 비슷하게 지원 받을까라는 생각을 했다.  방금 이 글을 쓰면서 검색했는데, 이 글의 옮긴 이인 '최유강'씨는 TFA의 한국화를 위해 '티치포올코리아'라는 단체를 만들어 활동하시는 것을 알았다. 교육이 중요하다고 생각하면서 행동으로 옮기지 못했는 데, 이를 직접 실천하시는 분을 보고 반성했다.

[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]



사용한 품목


1) 라즈베리파이B+ 베이직 키트: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005607887&LType=R


들어가면서


 지난 포스팅까지 라즈비안 위에 서버를 구성하고 텔레그램 봇을 설치까지 마쳤다. 이제 텔레그램 CLI를 실행시키기 위해 번호를 등록하고 테스트 코드를 돌려보도록 하겠다. 가상번호로 텔레그램 봇을 만들어서라즈베리파이에 있는 텔레그램 번호와 내 폰의 텔레그램이 달라야 명령을 내릴 수 있다고 착각했다. 메일의 '내게쓰기'기능처럼 텔레그램도 나에게 메세지를 보낼 수 있었고 이를 이용해서 반응하도록 했다. 아래 URL을 참고했다. 자 이제 본격적으로 텔레그램 봇에 대해 이야기 해보도록 하자.

http://humit.tistory.com/62

Voxox



  처음에는 voxox라는 어플을 이용하여 가상번호를 만들려고 했다. 이 어플로 전화를 받거나 메세지를 받기 위해서는 결제를 해야 된다는 정보를 보고 '뭐, 1달러정도는 할 수 있다'라고 생각했다가 실수로 두번 결제했다. 으아ㅏㅏㅏㅏㅏ. $2.86가 바보 같이 내가 결제한 증거다. 



 생각해보니 내가 폰에 설치한 텔레그램은 이미 내 폰번호로 등록되어 있었다. 그러므로 텔레그램을 새롭게 쓰기 위해서는 번호를 등록해야 하고, 폰에 설치한 텔레그램에 등록된 번호를 voxox 로 받은 가상번호로 바꿔야했다. 근데 바꾸기 위해서는 텔레그램 서버로부터 코드를 받아야 하는데 그게 쉽지 않았다. 일반적으로 voxox는 아이패드나 블루스택, 지니모션과 같이 전화기능이 없는 환경에서 사용한다. voxox 어플을 설치하고 가상번호를 받아 전화로 쓰거나 카카오톡, 텔레그램을 쓰는 것이다. 그러므로 voxox를 사용하여 굳이 지금 내 폰에 등록된 텔레그램의 번호를 가상번호를 바꿀 필요가 없다는 결론을 내렸다.(블루스택은 기숙사에 서버로 쓰는 컴퓨터에 있어서 지금 당장 해볼 수 없었던 이유도 있었다),(문자로 코드도 안오는 이유도 있었다.)


'내게 쓰기' 기능과 간단한 텔레그램 봇


 그래서 '내게 쓰기'기능을 이용해보자고 생각했고, 내 번호를 직접 연락처에 넣고 메세지를 날렸다. 카카오톡에서 해보지 않았고 안될 것 같은 느낌이 들었는데, 텔레그램에서 되서 얼마나 기뻤는지 모른다. 


▲좋다!

아래와 같이 번호와 이름을 등록하면 login메세지가 뜬다. 처음에는 메모를 위한 봇을 원했지만, 어벤져스를 보면서 나도 자비스같은 봇을 가지고 싶었다. 생각 같은 것도 정리해두고 스크립트 같은 것을 만들어두고 텔레그램으로 명령을 내리면 자동으로 해주는 것을 하나하나 만들어 갈 예정이다. 훗 재밌겠군


이제 전화번호 등록도 됬으니까 소스를 짜보도록 하자. 간단하게 hello를 입력하면 world를 출력해주는 봇을 만들 것이다. 이것이 의미가 있는 것이 내 명령에 반응을 했다는 것을 의미하므로 world 출력하는 것 대신에 서버의 db에 접근하여 자료를 검색하고 출력하도록 만들 수 있다. 또, 텔레그램 봇에서도 사진을 보낼 수 있으므로 나만의 사진저장소, 짤방저장소를 만들 수 있을 것 같다 ^오^

1
2
3
4
5
6
7
8
9
function on_msg_receive(msg)
        if(string.lower(msg.text)=="hello")then
            mark_read(msg.from.print_name, ok_cb, false)
            send_msg(msg.from.print_name, "world", ok_cb, false)
        end
end
 
function ok_cb(extra, secces, result)
end
cs

 lua를 포스팅을 하며 처음 만져보므로 소스에 대한 내용을 이야기는 다음 포스팅에서 하도록 하겠다. 간단하게 말하고 넘어가자면 msg.text를 lower로 소문자를 만들어 "hello"라면 send_msg를 이용하여 "world"를 보내는 것이라 직관적으로 쉽게 알 수 있다. 아래 그림은 hello 명령을 폰에서 날렸을 때 텔레그램 봇에서 world를 보내도록 한 것이다.



 또 재밌는 것은 텔레그램은 웹버전도 제공한다는 것이다. 웹 브라우저에서 텔레그램 인증을 통해 바로바로 명령을 날릴 수 있다. 이를 활용할 수 있는 부분을 생각해봤는데, 외부망에서 사내 서버에 직접적으로 접근하지 않고 텔레그램을 이용하여 서버의 상태를 볼 때 사용할 수 있을 거라 본다. 아래 그림은 웹버전의 텔레그램이다.




마치면서


 이번 포스팅에서 내 명령에 반응하는 간단한 텔레그램 봇을 만들어봤다. 생각보다 텔레그램이 가진 기능이 많아서 재밌는 것을 많이 할 수 있을 것 같다. 흥미진진하다. 또, 웹에서도 텔레그램 봇에 접근가능함을 보였다. 그러므로 웹이나 폰에서 텔레그램 봇에 명령을 전달하면 봇은 서버에 담긴 데이터들(사진, 메모 등)을 나에게 보낼 것이다. 물론 이에 대한 내용은 차근차근히 다음 포스팅에 담도록 하겠다..

관련 상품


라즈베리파이2 보드: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005652343

라즈베리파이2 베이직 키트: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005655515

손톱두이노: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005668577

라즈베리파이 전용 방열판 (소): 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P002110427





[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]



  1. 2017.08.15 08:42

    비밀댓글입니다

[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]



사용한 품목


1) 라즈베리파이B+ 베이직 키트: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005607887&LType=R


서론


 지난 포스팅까지 라즈비안위에 서버를 구성했다. 이제는 라즈비안에 텔레그램을 설치해야 한다. 기본적인 구성은 라즈비안 위에 서버와 텔레그램이 병렬적으로 돌아가고 텔레그램이 나의 명령을 받아서 서버의 웹과 데이터베이스에 접근하는 구조를 가진다. 설치하는 방법은 아래 3개의 URL을 참고했다.

http://coffeenix.net/board_view.php?bd_code=1759

http://humit.tistory.com/57

https://github.com/vysheng/tg/blob/master/README.md

설치



  설치할 때 먼저 관련 라이브러리들을 설치해야 한다. 그런데 문제는 repository가 잘못 됬는지 repository를 못 찾는 지 라이브러리들을 가져오지 못했다. 무엇이 문제일까? 평소에 라이브러리를 가져오지 못하는 문제는 repository를 찾지못해서였고, 이 문제는 dns와 관련이 있었다. 그래서 /etc/network/interfaces를 아래와 같이 변경했고 문제를 해결했다. 물론 변경 후 네트워크 서비스를 재시작해야 한다. dns서버를 기존에는 한국 코넷?쪽으로 해놨다가 구글 dns서버의 IP인 8.8.8.8로 바꿔줬다.



라이브러리를 다운받기 전에 아래 명령어를 입력해서 업데이트를 해주자. 

1
2
sudo apt-get update
sudo apt-get upgrade
cs

 그리고 아래 명령어를 입력하도록 하자. 

1
apt-get install libreadline-dev libconfig-dev libssl-dev lua5.2 liblua5.2-dev libevent-dev
cs


 업데이트를 해서 그런지 아래 그림과 같이 라이브러리를 있다고 했다. 물론 없으면 설치해주도록 하자. 설치하다가 딴거 하다가 그래서 중간에 라이브러리를 직접 설치해줬는 지 기억이 안난다. :(


그럼 이제 텔레그램 CLI를 설치하기 위한 환경은 모두 갖췄다. CLI는 Command Line Interface로 터미널을 통해 사용자와 컴퓨터가 상호 작용을 하는 방식을 말한다. 우리는 이 텔레그램 CLI를 이용하여 DB나 웹에 접근할 것이고, 개인적으로 CLI가 편하다고 생각할 뿐더러 CLI외에 텔레그램을 db와 웹에 접근하는 방법이 딱히 생각나지 않아서 텔레그램 CLI를 선택했다 ^오^

 처음에는 블로그를 참조해서 wget를 이용해서 다운받았는데, configure 문제가 아래와 같이 있었다. 그래서 github에 제작자가 만들어 둔 방법을 사용하니 바로 됬다. 역시 만든 사람이 제일 잘 아는 것 같다.

./configure명령을 날리면 체크를 하다가 마지막에 에러를 뱉고 진행이 안된다. 


그 문제가 python에 있길래 python 관련 configure를 처리하기 위해 어떻게 해야할까 고민했다. 그러다가 파이썬 관련 configure를 관리하기 위해 apt-get install을 이용하는 포스팅을 봤고 아래와 같이 했지만 여전히 안됬다.


위에서 언급한 것과 같이 제작자가 readme에 적어둔 대로 git clone명령으로 설치했다.(원래는 wget을 해서 안됬다. 물론 wget의 문제가 아니라 내가 중간에 뭘 잘못 했을 지도 모른다.)

1
git clone --recursive https://github.com/vysheng/tg.git && cd tg
cs

 이렇게 설치하면 tg 디렉토리로 들어가는데 ./configure와 make를 하면 컴파일을 한다.

1
2
./configure
make
cs

아래 그림은 git clone으로 설치해서 cd로 해당 디렉토리로 이동하고 ./configure와  make를 한다. 뭐가 문제인 지는 모르겠지만 컴파일이 오래 걸리길래 딴 걸 했는데 대충 1시간은 지난거 같다. (그만큼 용량이 크나? 라즈베리파이가 문제인건가?)



컴파일을 하고 아래 명령어를 쳐서 번호를 물으면 올바르게 설치 된 것이다. 




마치면서


설치하면서 라이브러리때문에 많은 시간이 걸렸다. 역시 새로운 환경에서 개발을 한다는 것은 개발보다 환경구축에 많은 심력을 소모하게 된다는 나의 지론(?!)을 다시 생각나게 했다. 그리고 다음 포스팅에는 내 텔레그램으로 봇에 명령을 내리기 위해서 가상번호를 만들면서 생긴 우여곡절기와 간단히 만든 텔레그램 봇을 보여주도록 하겠다.

관련 상품


라즈베리파이2 보드: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005652343

라즈베리파이2 베이직 키트: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005655515

손톱두이노: 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P005668577

라즈베리파이 전용 방열판 (소): 

http://www.icbanq.com/shop/product_detail.asp?prod_code=P002110427





[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로, 아이씨뱅큐의 지원을 받아 작성되었습니다]





들어가면서


[1년에 100권 제대로 읽기]의 세번째 책이다. 두번째 책은 포기하는 용기인데, 포스팅 해야겠다는 생각을 이 책부터 하면서 건너 뛰게 되었다. 물론 꼭 다음에 할 생각이다 ㅎㅎ. 이 책에서 읽기 전에는 그저 그런 이야기만을 할 줄 알고 입을 삐쭉 내밀고 삐딱한 시선을 가지고 봤다. 하지만 역시나 편견은 잘못된 것이라는 것을 다시 한번 깨닫게 됬다. 이제 이 책에 대해서 한번 이야기해보도록 한다. 언제나 그랬듯이 목차를 보고 넘어가도록 하자.

  • 나의 선택하는 힘은 어느정도인가

  • 이유를 알아도 여전히 선택이 힘든 이유

  • 선택하는 힘을 기르는 방법

위와 같은 순서로 이 책은 구성되어 있으며, 나는 이 중에서 가장 기억에 남는 '선택하는 힘을 기르는 방법'에 대해 이야기 해보려고 한다.

선택하는 힘을 기르는 방법


선택하는 힘을 기르는 방법에 대한 이야기는 아니지만, 먼저 내가 저지르고 있던 실수에 대해 이야기하고자 한다. 평소에 선택을 못한다고 생각하지는 않았다. 하지만 고민을 나 스스로 만드는 행위를 했던 것을 이 책을 통해 알게 됬다. 이 책에서는 사람들은 예측가능성과 통제가능성의 노예라고 했다. 미래를 예측하고 그에 대비(통제)하기 위해 노력한다고 한다. 하지만 우리는 미래에 일어 날 일에 대한 모든 가능성을 예측 할 수 없으며, 예측했다고 하더라도 모두 통제할 수 없다는 것을 받아들이지 않는다. 왜냐하면 우리는 애매한 것을 싫어하기 때문이다. 마치 처음 ollydbg로 디버깅할 때 주변에 가득찬 알 수 없는 것들에 대한 불안감과 애매함이 내가 제대로 공부하고 있는 것인지 아닌 지 찝찝한 기분을 드는 것과 같다는 생각을 했다. 

 그러므로 예측을 하고 통제 가능하도록 대비는 하겠지만, 100%로 완벽하게 예측하고 통제하기 위해 노력을 하는 것이 잘못 된 것이라고 한다. 실수가 있더라도 그를 통해 교훈을 얻을 생각을 가지고 고민 할 시간에 앞으로 나아가라는 말이다. 이왕 실수를 할 빠에 빨리 실수를 얻고 교훈을 얻자는 것이다. 그러면 그 동안 받을 스트레스는 없는 것이 없다는 것이다. 그리고 통제 못하는 상황이 그렇게 생각보다 힘들지 않는데, 자신이 통제 못하여 상처를 받을 미래에 대해 과대평가 한다고 한다. 힘들더라도 우리의 슬픔이 계속 지속되는 것이 아닌데 너무 걱정한다는 것이다.

 이제 선택하는 힘을 기르는 이야기를 하겠다. 그 중에서 가장 기억에 남는 것은 아래와 같은 2개다.

  • 확대해석 하지 말고 확대 적용하라

  • quick-win으로 승부하라

 확대해석하지 말고 확대 적용하라는 것은 떤 상황에 대한 불안감으로 망설이지 말고 지금 내가 잘 할 수 있는 것을 알고 이를 응용하라는 것이다. 바둑기사 조훈현 9단의 예시를 책에서 든다. 유명한 바둑기사인 조훈현9단이 외국에 나갔을 때 체스마스터들이 하는 경기를 보면서 다른 룰을 가진 게임을 보며 호기심 어린 눈으로 봤다. 한번도 체스를 해본 적 없는 조훈현씨에게 체스마스터가 체스를 하자고 했고, 결과는 조훈현씨의 승리로 이어졌다. 경기가 끝나고 조훈현씨는 이전 경기를 보던 양상과 같이 경기가 흘러가 그대로 두어 이기게 되었다고 했다. 바둑을 하면서 가진 속기능력을 여기서 발휘한 것이다. 현재 처한 상황을 헤쳐나가기 위해서 자신이 잘하는 것들을 알고 이를 적용하고 응용시키면서 문제를 해결해 나가면 된다. 사족으로 이에 대한 상황(조훈현씨가 체스마트서에게 이겼다)이 확실하지 않아서 검색 해 봤는데, 이긴 것은 맞지만 체스마스터가 맞는지 아닌지는 확실히 밝혀진 것 같지 않다.

링크

 이 부분은 누구나 쉽게 적용할 수 있고 당연하게 생각하는 것이라고 생각한다. 큰 일을 작은 일로 나누어서 빠르게 일을 해결해 나가면서 성취감을 느끼면서 나아가는 것이다. 마치 와우(월드오브워크래프트의 줄임말)에서 긴 퀘스트가 아니라 작은 퀘스트를 연결해 놓은 연계퀘스트가 있는 것과 같다. 위에서 말한 확대적용을 고려하면 내가 못하는 부분이나 처음 접하는 부분이 있더라도 잘게 잘게 쪼개 목표치를 낮추고 내가 할 수 있는 일들로 성취감을 얻으며 나아가는 것이다. 

 

기억에 남는 문장들


 우리는 대부분 바꿀 수 없는 것을 바꾸려는 집착과 바꿀 수 있는 행도응ㄴ 바꾸지 않는 고집을 갖고 있다.

 심리학자들은 우리의 감정을 크게 '행복, 놀라움, 두려움, 분노, 슬픔, 혐오감, 경멸감'이라는 가지의 핵심 감정으로 나눈다. 긍정적 감정은 행복 하나이고, 이쪽저쪽 될 수 있는 중립적인 감정은 놀라움이다. 나머지 5가지는 모두 부정적인 것이다. 감정에 부정적인 것이 많은 것은 그만큼 생존을 위해서 자기를 방어할 필요성이 더 많기 때문이다.

 우리는 어떤 일을 시작할 때 그 최정 결과를 미리 정확히 알지 못한다. 지금 '뒤돌아보니' 그렇게 충분히 알 수 있었던 것처럼 느껴지는 것뿐이다. 앞서 설명한 것처럼, 이는 '사후설명 편향'이다.

 사람들은 어떤 사건이 발생하고 나면, 과거에도 현재에 알고 있는 사실(결과)을 알고 있던 것처럼 기억을 재구성하기 때문이다. 그래서 과거에 현재(당시의 미래)를 실제보다 잘 예측했던 것처럼 설명하며, 현재의 사건도 과거의 어떤 일이 만든 인과관계 때문에 벌어질 수 밖에 없던 것으로 묘사한다.

 학생은 처음에는 정답을 골랐다가도 왠지 아닌 것 같아 답안을 고쳐 나빠진 성적표를 손에 쥐고 오열한다. 심리학적으로는 자신에게 벌어지는 일에 대해 너무 많은 생각을 할 때나, 반대로 너무 부주의할 때 위와 같은 상황이 벌어진다. 이런 상황을 전문 용어로 초킹이라고 한다. 부주의에 의한 초킹은 더 집중력을 키우도록 동기화를 시키면 어느 정도 해결 될 수 있다. 하지만 지나친 분석과 생각에 의해 정상적인 행동이 마비되는 초킹은 복잡하다. 왜냐하면 초킹에 대한 분석 자체가 또 생각을 과도하게 만들고 복잡하게 해서 행동을 해야 할 순간에 분석에만 매달리게 할 위험이 있기 때문이다.


마치면서


 원래 포스팅을 하면서 뭔가 완벽하게 하고 싶어 책을 다시 읽고 목차도 다시 보고 생각도 다시 하곤 했다. 하지만 이 책을 읽으면서 발전해 나가는 것에 의의를 두는 것이 맞다고 생각했다. 처음부터 잘 할 수 없음을 인정하고 꾸준하게 포스팅을 하다 보면 글로 내 생각을 표현하는 능력이 더욱 커질 것이라 믿는다. 완벽주의 연구로 유명한 고든 프렛 박사는 

"시행착오로 발전을 추구하는 것과 완벽을 추구하는 것은 다르다. 

완벽의 추구는 자기비하와 만성적 스트레스의 레시피"


라고 말한 것처럼 앞으로 나가면서 발생하는 시행착오와 실수를 받아들이고 교훈을 얻어 나 스스로 변화를 만들어야 겠다는 생각을 하며 이 포스팅을 마친다.



들어가면서


 

 [1년 100권 제대로 읽기]를 시작하면서 처음 미션도서를 받았다. 이름하여 '미움받을 용기'. 6월 4일까지 다 읽고 준비를 해야 하는데 6월 2일날 택배가 도착했다. 또, 12시이후에 경비아저씨게 택배를 찾으러 갔는데 하필 12시부터 아침 6시사이에는 택배 물품을 주지 않는다고 하여 다음날 아침에야 받을 수 있었다. 내게 남은 시간이 별로 없어서 시간을 쪼개쪼개 읽는 바람에 연속성이 떨어져 한번에 이해되지 않았다.(물론, 쭉 읽었어도 한번에 이해되지 않았을 것 같다ㅎㅎ). 

 지그문트 프로이트, 칼 융과 더불러 3대 심리학자라고 불리는 알프레드 아들러가 주장하는 개인심리학에 대한 내용이 담겨 있다. 간단하게 알프레드 아들러에 대해 알아봤었는데 프로이트와 같이 오스트리아에서 출생이며, 정신과의사였다. 프로이트가 운영하는 빈정신분석협회의 핵심일원으로 활약하다가 학설의 대립으로 나왔다고 한다. 다음에 다른 책을 더 읽고 난 뒤에 아들러에 대해 알아보는 걸로 하고 아들러에 대한 소개는 여기까지 하려고 한다. 소크라테스의 철학을 플라톤이 책으로 만들어 후대에 전한 것처럼 이 책의 저자인 기시미 이치로는 아들러의 플라톤이라고 스스로 칭한다.

 이 책은 아래와 같은 5개의 장으로 이루어져 있다. 아래 항목들에 대해 한 주씩 포스팅 해도록 하겠다. 처음에는 이 책의 전체를 다루고 싶었지만, 내가 이 책에서 이야기하고자 하는 바를 제대로 이해하고 있는 지 확신하기 어려웠다. 물론 계속보더라도 내 나름의 해석을 하겠지만, 포스팅을 위한 독서노트가 되는 것이 아니라 독서노트를 위한 포스팅이 되어야 한다는 생각때문이다.

  • 트라우마를 부정하라
  • 모든 고민은 인간관계에서 비롯된다.
  • 타인의 과제를 버리라
  • 세계의 중심은 어디에 있는가
  • '지금, 여기'를 진지하게 살아간다.

이에 대해 하나하나 내 생각을 적어보고자 한다.

트라우마를 부정하라


 트라우마를 부정하라는 말은 프로이트가 말하는 '원인론'을 부정하는 것다 .그럼 프로이트가 말하는 '원인론'은 무엇이고, '원인론'은 무엇일까? '원인론'은 "현재의 결과가 과거의 원인때문에 발생한 것이다." 라는 것이다. 그러면 이것을 바꿔 말하면 과거의 원인때문에 현재의 결과가 생기는 것이고 이는 자신을 합리화하는 수단이 되고, 원인이 같다면 결과도 같다는 것이 된다. 예를 들면 속담 "종로에서 뺨맞고 한강에서 화풀이한다"라는 속담을 생각해보자. 이에 대한 내용은 아래 링크에 잘 나와있다. 

http://tip.daum.net/question/38864277

 상황의 요지는 "종로의 시전에서 흥정 끝에 위세 높은 상인과 시비가 벌어져도 아무소리 못하다가 한강의 난전에 가서 힘없는 상인에게 화풀이한다는 뜻"이다. 이는 뺨을 맞은 원인이 화를 내는 결과가 바로 이어져야 하는데 상대적으로 위세 높은 상인에게는 화를 숨겼다가 힘없는 상인에게 화를 낸다. 어? 이것봐라? 이는 우리가 충분히 알고 있는 내용이다. 상대적으로 높은 사람이 화를 만들어도 참을수 있다는 것이다. 하지만 화를 못참고 버럭 소리를 질렀다라는 이야기도 있다. 이는 화에 굴복하여 어쩔 수 없이(내 의지와 상관없이) 버럭 소리를 질렀는 것이 아니라 앞에 있는 사람이 나보다 상대적으로 높은 사람이 아니기에 내 스스로 버럭 소리를 질러도 된다고 생각을 했기 때문에 소리를 지른것이다. 이는 하나의 원인이 하나의 결과로 이어지는 것이 아니라 하나의 원인이 상황에 따라 다른 결과를 만든다. 


▲지금 이 트라우마는 내가 선택한 걸까?

 그러므로 '트라우마'라는 원인이 다른 결과로도 충분히 이어질 수 있는 것이다. 이 책을 읽기 전까지는 나도 어릴적 고통스런 기억(트라우마)이(가) 현재 삶에 특정한(잘못된) 방향으로 영향을 미친다라고 확신하고 있었다. 하지만 이 책에서는 그렇게 생각하지 않는다. 영향을 미치는 것은 맞지만 '내가 어떤 의미를 부여하느냐'에 따라서 영향이 다르다는 것을 의미한다. 위의 속다 지금 내 화의 대상이 상대적으로 높은 경우에는 화를 숨기고, 상대적으로 낮은 경우에는 화를 내는 것처럼, 과거의 고통스러운 삶을 살았더라도 현재의 삶에서 좋은 의미를 부여하여  내가 단단하게 되는 계기라고 생각할 수도 있고 그때의 아픈기억때문에 지금 내 상태가 이상하다라고 변명할 수도 있다는 것이다.

 과거의 원인때문에 '나는 다혈질이야'라고 자신의 성격을 규정하고 바꿀 수 없다고 단정하는 것은 잘못된 것이라고 한다. 인간은 자신이 의미를 부여하고 해석한 것을 토대로 바꿀 수 있는 세계관, 생활양식을 통해 살아간다. 그러므로 경험과 생각을 통한 의미부여가 현재 자신이 살아가는 '생활양식'을 결정한다. 이 책에서 재밌다고 느껴진 것은 사람들은 자신의 성격이 바꿀 수 없는 것이라고 단정하면서 불안을 없앤다고 한다. 성격을 바꿔서 생기는 불확실한 미래보다는 조금 불편하겠지만 지금까지 살아 온 '예측 가능한 성격'으로 살아가려고 한다. 그러므로 현재의 불편을 극복하기 위해서 지금의 성격을 바꿀 수 없다는 생각을 버리는 것이 변화의 시작이라고 말한다.


마치면서


 이 장에서 하는 말은 사람은 각자의 주관적인 세계에 살아가면서 바꿀 수 없는 성격과 현실을 선택한다. 이렇게 선택한 성격과 현실을 자신을 합리화를 위한 수단으로 사용한다. '왜 변화하지 않느냐?'에 대한 이유가 있으므로 현재를 바꿀 필요가 없다는 것이다. 

나도 지금 '지금, 현재'에 집중하는 것이 아니라 '과거'에 집중하면서 내가 왜 지금 이런 상황에서 불평을 하는 지에 대한 이유만 늘어놨다. 지금 내가 부족한 것에 대해 말하는 것이 아니라, 부족한 것을 인식하고 지금 내가 무엇을 할 수 있는 가에 대해 집중하기로 했다. 

 이 책을 보다가 '대증요법'이라는 재밌는 표현을 봤다. 사람이 병에 걸리면 병에 걸리는 원이과 증상이 있다. 감기에 걸리는 원인은 바이러스이고, 증상은 기침이라는 것과 같다고 볼 수 있다. 여기서 원인인 바이러스를 없애는 것은 '원인요법'이고, 증상인 기침을 없애는 것을 '대증요법'이라고 한다. 내 행동이 '대증요법'처럼 어떤 문제를 발생시키는 원인과 기반에 초점이 맞춰져 있는 것이 아니라 일시적인 미봉책에 불과한 '증상'에 초점이 맞춰져 있지 않을까 라는 생각ㅇㄹ 했다. 이를 막기 위해 조금이라도 더 생각하고, 많은 책을 읽으며 포스팅을 이어 갈 생각이다. 

  1. 우사미3 2015.06.12 17:11 신고

    2탄도 빨리 보고 싶네요

+ Recent posts