[첫화면으로]Perl/Perlbrew

마지막으로 [b]

요놈이 뭐하는 건지는 아래 참고 링크들 읽어보면 잘 나와 있다.

여기서는 주인장이 perlbrew를 쓰면서 겪었던 사항을 정리.

1. 새 버전의 Perl을 인스톨 할 때 옵션
1.1. 인스톨 과정의 에러
2. local::lib 와 충돌
2.1. perlbrew 자체의 중복 문제
2.2. 추가 설치한 CPAN 모듈들의 공유
2.3. 시스템 펄과 추가 설치한 펄 사이의 스위칭
2.4. 정리
3. 추가 모듈 일괄 설치
4. crontab 에 적용
5. screen 위에서 스위칭
6. CGI 스크립트의 스위칭
7. 0.60 버전의 환경 변수 설정 버그
8. 참고
9. Comments

1. 새 버전의 Perl을 인스톨 할 때 옵션

다른 건 모르겠고 -Dusethreads는 꼭 넣어서 쓰레드를 지원하도록 컴파일하는 게 좋다고 함.1

1.1. 인스톨 과정의 에러

perl 설치 과정 중에 다음과 같은 에러가 난다.
IO.xs: In function ‘XS_IO__Poll__poll’:
IO.xs:311: error: invalid application of ‘sizeof’ to incomplete type ‘struct pollfd’
IO.xs:315: error: invalid use of undefined type ‘struct pollfd’
IO.xs:315: error: dereferencing pointer to incomplete type
...

구글링해서 나온 위 글을 보아하니, 개인적으로 세팅해둔 C include 경로가 있을 때 충돌의 여지가 있는 것 같다. 내 경우는 $CPATH 변수 때문이었음. 혹시나 몰라 $LD_LIBRARY_PATH 등도 다 끈 후 다시 시도하니 성공함.

2. local::lib 와 충돌

나는 이 gyparkwiki가 있는 서버에 root권한이 없기 때문에, 추가로 설치하는 모듈들은 다 개인 계정에 저장된다. 이 때 저장되는 위치를 지정하고, 차후에 스크립트를 실행할 때 그 모듈을 로드할 수 있도록 경로를 지정해야 하는데, 현재는 Cpan:local::lib 모듈을 사용하고 있다2

local::lib에서 사용할 베이스 디렉토리는 ~/local/perl이었고, 결과적으로 .bash_profile에 적어 준 코드에 의해서
eval $(perl -I$HOME/local/perl/lib/perl5 -Mlocal::lib=$HOME/local/perl)

내가 cpan 을 써서 설치하는 모듈들은 다음 경로에 저장되고, 이 두 경로는 PERL5LIB 환경 변수에 들어간다.

그런데 서버에 있는 펄이 5.8이라서 영 불편한 터라, 5.14를 설치하기 위해 perlbrew를 설치하였는데 여기서 여러 가지 면에서 충돌이 발생했다.

2.1. perlbrew 자체의 중복 문제

perlbrew 홈페이지에서 안내하는 대로 curl -kL http://install.perlbrew.pl | bash를 통해 설치했더니, perlbrew 실행파일이 ~/perl5/perlbrew/bin/ 아래에 설치되었다. 그런데 문제는 내가 예전에 CPAN을 통해서 Cpan:App::perlbrew를 설치한 적이 있었다는 것. 이 때 설치된 실행파일은 ~/local/perl/bin/ 아래에 있었다. 이걸 모른채로 진행을 했더니, 내가 현재 시스템 펄을 쓰고 있느냐 perl-5.14 를 쓰고 있냐에 따라서 서로 다른 perlbrew가 실행되는 경우가 있었다(확실히 확인하지는 못했음).

더 큰 문제는 원래 설치된 버전이 꽤나 오래 전 버전이라서(0.07. 현재 버전은 0.41), perlbrew의 동작 방식이 크게 바뀌었다는 점이다.

게다가 5.14를 설치한 상태에서 현재 사용 가능한 펄 리스트를 뽑아보면
$ perlbrew installed (이 installed라는 명령도 현 버전은 list로 바뀌었음)
perl-5.14.2
/usr/bin/perl
이렇게 나오는데, 시스템 펄로 돌아가기 위해서 perlbrew off를 하지 않고 switch를 했더만 그 이후로 5.14쪽으로 다시 스위치를 도저히 할 수가 없었다.

뒤늦게야 중복 설치되어 있다는 걸 깨닫고 구버전을 제거는 했는데, 뭐가 꼬였는지 그 후로도 스위칭이 잘 안 되어서, 결국 ~/perl5 를 싹 지우고 새로 시도했음.

2.2. 추가 설치한 CPAN 모듈들의 공유

그 다음은, 시스템 펄을 사용하면서 추가로 개인 계정에 설치한 CPAN 모듈들을 5.14에서도 쓸 수 없을까 하는 거였다. 아니면 전부 다시 설치해야 하는데 엄두가 안 나는 일이라서.

그래서 이리 저리 구글링해 봤는데, 녹록치 않아 보인다.

일단, 가장 큰 문제는 펄만으로 짜여진 모듈 말고 c 등을 써서 만들어진 XS모듈들은 펄의 메이저 버전이 바뀌면 호환이 되지 않는다는 점.
# perlbrew는 5.14를 쓰도록 지정된 상태에서 5.8 모듈 경로가 PERL5LIB 변수에 들어 있으면 이렇게 에러가 난다.
$ perlbrew switch perl-5.14.2
perl: symbol lookup error: /home/gypark/local/perl/lib/perl5/i386-linux-thread-multi/auto/IO/IO.so: undefined symbol: Perl_Tstack_sp_ptr

그나마 다행스럽게도(?), XS모듈이 들어가는 경로의 이름이 시스템 펄은 i386-linux-thread-multi였고, 5.14의 경우는 i686-linux-thread-multi였다. 그래서 순수 펄 모듈은 ~/local/perl/lib/perl5/ 아래에서 공유하고, XS모듈은 저 두 디렉토리 아래서 각각 관리하게 할 수 있지 않을까 싶긴 했는데...

그 다음은 ~/local/perl/bin/ 아래 설치되는 실행 스크립트들이 문제. 당장 perlbrew라거나, cpanm 등 스크립트들이, "5.14를 쓰도록 스위칭되고 있는 상황에서 PERL5LIB에 시스템 펄 쪽 모듈인 i386-linux-thread-multi 디렉토리가 추가되어 있으면" 여지없이 위와 같은 symbol lookup error를 낸다. 따라서 펄 스위칭을 할 때마다 PERL5LIB 값을 고쳐줘야 하는데, 앞으로도 잘 될지 보장도 없고 해서, 결국 다 포기하고 5.14용 모듈은 전부 설치하기로 함.

최종적으로 경로는 다음과 같이 잡힌다.
~
 /local/perl                              - local::lib 에서 관리하는 베이스 경로
                                            (Module::Build나 MakeMaker에서 install base로 지정됨)
            /bin                            - 실행 스크립트가 설치되는 곳
            /man                            - 맨페이지
            /lib                            - 모듈 설치
                /perl5                        - 순수 펄 모듈
                /i386-linux-thread-multi      - XS 모듈

 /perl5/perlbrew                          - $PERLBREW_ROOT
                /bin                        - perlbrew, patchperl, cpanm 이 설치됨
                /perls                      - perlbrew install 명령으로 설치하는 배포본들이 이 아래 설치됨
                      /perl-5.14.2            - perl-5.14.2 로 스위칭했을 때 $PERLBREW_PERL 값이 'perl-5.14.2'로 설정
                                  /bin          - 실행 스크립트
                                  /man          - 맨페이지, $PERLBREW_MANPATH
                                  /lib
                                      /5.14.2                          - 코어 모듈들이 여기에 설치됨
                                             /i686-linux-thread-multi  - 코어 모듈 중 XS 모듈들
                                      /site_perl                       
                                                /5.14.2                         - cpan을 사용하여 설치하는 추가 모듈
                                                       /i686-linux-thread-multi - 추가 모듈 중 XS 모듈
                      /perl-5.12.4
                      /perl-5.10.1
                        ...

즉 cpan을 써서 추가로 설치한 모듈들은 ~/perl5/perlbrew/perls/perl-5.14.2/lib/site_perl/5.14.2 또는 그 아래 i686-linux-thread-multi에 설치됨.

2.3. 시스템 펄과 추가 설치한 펄 사이의 스위칭

perlbrew switch로 추가 설치한 펄로 스위칭하거나, perlbrew switch-off로 시스템 펄로 되돌릴 수 있는데, 시스템 펄을 쓰는 경우에만 local::lib가 적용되어야 한다. 따라서 .bash_profile에 다음과 같이 해 주었다.

# perlbrew에 의한 설정을 먼저 적용한다
if [ -f $HOME/perl5/perlbrew/etc/bashrc ]
then
    source /home/gypark/perl5/perlbrew/etc/bashrc
fi

# $PERLBREW_PERL 변수의 값이 빈 스트링인 경우는 off 상태이다.
# 이 때만 local::lib 의 설정을 적용한다.
if [ "$PERLBREW_PERL" == "" ]
then
    eval $(perl -I$HOME/local/perl/lib/perl5 -Mlocal::lib=$HOME/local/perl)
fi

# 마지막으로, 내가 따로 만들어 쓰는 모듈이 들어가는 경로를 추가
export PERL5LIB=$HOME/git/myperlmodules:$PERL5LIB

이렇게 해서, 로그인하는 시점에 local::lib 설정을 적용할지 말지를 결정할 수 있다.

남은 문제는, 로그인한 후에 perlbrew 를 써서 시스템 펄과 추가 설치한 펄 사이를 오갈 때 local::lib 에 의한 설정을 적용했다 없앴다 하는 과정이 필요하다는 것이다. (특히나 시스템 펄에서 추가 설치한 펄로 스위칭할 때, PERL5LIB 변수의 값 때문에 여기서도 심볼 룩업 에러가 난다)

이것은, 로그인할 때 불리는 perlbrew/etc/bashrc를 고쳐주었다. 이 부분은 정확히 고친 건지 확신은 없지만, 테스트해보면 잘 동작하는 듯.
--- bashrc.original 2012-02-23 01:48:35.000000000 +0900
+++ bashrc  2012-02-23 04:40:10.000000000 +0900
@@ -39,6 +39,28 @@
 }
 __perlbrew_set_path

+# local::lib와 혼용을 위한 설정
+# 아래 두 변수의 값을 자신의 환경에 맞춰 적어줌
+_LOCAL_LIB_INC="$HOME/local/perl/lib/perl5"
+_LOCAL_LIB_ROOT="$HOME/local/perl"
+
+# local::lib 에 의한 설정을 제거
+__unset_local_lib () {
+    export PERL5LIB="$PERL5LIB"
+    eval $(perl -I$_LOCAL_LIB_INC -Mlocal::lib=--deactivate-all,$_LOCAL_LIB_ROOT)
+}
+
+# local::lib 설정 적용
+__set_local_lib () {
+    eval $(perl -I$_LOCAL_LIB_INC -Mlocal::lib=--deactivate-all,$_LOCAL_LIB_ROOT)
+    export _MY_PERL5LIB="$PERL5LIB"
+    eval $(perl -I$_LOCAL_LIB_INC -Mlocal::lib=$_LOCAL_LIB_ROOT)
+    if [ -n "$_MY_PERL5LIB" ]; then
+        export PERL5LIB="$(perl -e 'print join ":", $ENV{_MY_PERL5LIB}, grep { index($_, $ENV{_MY_PERL5LIB}) } split/:/,$ENV{PERL5LIB};')"
+    fi
+    unset _MY_PERL5LIB
+}
+
 perlbrew () {
     local exit_status
     local short_option
@@ -70,6 +92,7 @@
                         eval $line
                     done
                     IFS=$OLD_IFS
+                    __unset_local_lib
                     __perlbrew_set_path
                 fi
             fi
@@ -79,6 +102,7 @@
               if [[ -z "$2" ]] ; then
                   command perlbrew switch
               else
+                  __unset_local_lib
                   perlbrew use $2
                   __perlbrew_reinit $2
               fi
@@ -88,12 +112,14 @@
             unset PERLBREW_PERL
             eval `perlbrew env`
             __perlbrew_set_path
+            __set_local_lib
             echo "perlbrew is turned off."
             ;;

         (switch-off)
             unset PERLBREW_PERL
             __perlbrew_reinit
+            __set_local_lib
             echo "perlbrew is switched off."
             ;;

펄 버전, @INC, 환경변수, PATH를 출력하는 스크립트를 만들어서 테스트해 보았다:
[gypark@www temp]$ perlbrew list
* perl-5.14.2
[gypark@www temp]$ ./t.pl
version: 5.014002
/home/gypark/git/myperlmodules          (<----- 로그인할 때 추가로 지정해 준 PERL5LIB 경로)
/home/gypark/perl5/perlbrew/perls/perl-5.14.2/lib/site_perl/5.14.2/i686-linux-thread-multi     (<----- perlbrew 모듈 경로)
(생략)
.
----------------
[PERL5LIB][/home/gypark/git/myperlmodules]
(생략)
[PERLBREW_PERL][perl-5.14.2]          (<----- 현재 사용하도록 설정된 펄)
(생략)

----------------
[PATH]
/home/gypark/perl5/perlbrew/bin
/home/gypark/perl5/perlbrew/perls/perl-5.14.2/bin          (<----- 현재 사용하는 펄의 path)
/home/gypark/bin
(생략)

[gypark@www temp]$ perlbrew off          (<----- off 해서 끄면)
perlbrew is turned off.

[gypark@www temp]$ ./t.pl
version: 5.008008          (<----- 버전이 5.8.8로 돌아가고)
/home/gypark/git/myperlmodules          (<----- 이 경로는 여전히 제일 위에 남고)
/home/gypark/local/perl/lib/perl5/i386-linux-thread-multi          (<----- 여기 3줄이 local::lib의 적용)
/home/gypark/local/perl/lib/perl5/i386-linux-thread-multi
/home/gypark/local/perl/lib/perl5
/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi          (<----- 시스템 펄의 모듈 경로)
(생략)
.
----------------
[PERL5LIB][/home/gypark/git/myperlmodules:/home/gypark/local/perl/lib/perl5/i386-linux-thread-multi:/home/gypark/local/perl/lib/perl5]
(생략)
[PERLBREW_PERL][]          (<----- perlbrew가 꺼졌음)
(생략)
[PERL_LOCAL_LIB_ROOT][/home/gypark/local/perl]          (<----- 이 3줄에 있는 변수들도 local::lib 적용으로 생긴 것)
[PERL_MB_OPT][--install_base /home/gypark/local/perl]
[PERL_MM_OPT][INSTALL_BASE=/home/gypark/local/perl]

----------------
[PATH]
/home/gypark/local/perl/bin          (<----- local::lib의 적용)
/home/gypark/perl5/perlbrew/bin          (<----- 이 아래 5.14.2 path는 사라졌음)
/home/gypark/bin
(생략)

2.4. 정리

정리하면

3. 추가 모듈 일괄 설치

5.8을 쓰면서 추가로 설치하여 ~/local/perl 내에 설치한 모듈들을 다시 5.14에도 설치해야 했는데, 그러려면 목록을 얻어야 한다.

여담으로, cpan을 실행했더니만 명령행 히스토리 기능이 동작을 안 하더라. Term::ReadLine::Perl을 추가로 설치해주면 된다.

한가지 더, perlbrew install-cpanm하면 cpanm을 따로 $PERLBREW_ROOT/bin 아래 설치하여 현재 스위칭한 펄에 무관하게 쓸 수 있게 해 준다.

4. crontab 에 적용

이 서버에는 RSS를 만들기 위해 crontab을 써서 일정 시간마다 실행되는 스크립트들이 있다. 그런데 이것 때문에 좀 고생을 하게 되었다:

crontab상에서 .bashrc나 .bash_profile등의 스타트업 파일을 불러오는 방법은 못 찾았다6

별 수 없이 crontab의 각 항목마다 각각 설정해줘야 했는데, 대충 다음 두 가지 방법을 찾았음

1) 명시적으로 사용할 펄 버전을 지정하는 방법7
PERLBREW_PERL="perl-5.14.2"
10 0 * * *   PATH="$HOME/perl5/perlbrew/perls/$PERLBREW_PERL/bin:$PATH" /usr/bin/env perl /some/script_path
# 또는 환경 변수를 쓰지 않고
10 0 * * *   $HOME/perl5/perlbrew/perls/perl-5.14.2/bin/perl /some/script_path
또는 perl을 실행하지 않고 곧바로 스크립트 이름을 적는 경우:
10 0 * * *   PATH="$HOME/perl5/perlbrew/perls/perl-5.14.2/bin:$PATH" /some/script_path

2) perlbrew에서 스위칭한 펄을 사용하도록 하는 방법 (권장하지는 않음 - 아래 라슈펠님 커멘트 참조)
10 0 * * *   /bin/bash --login -c "/some/script_path"

perlbrew를 써서 최신 버전의 펄을 사용하는 경우는

아니면 그냥 crontab을 통해 실행할때는 시스템 펄을 사용하도록 하고, 다만 모듈 버전이 문제가 되니 crontab에 PERL5LIB 변수를 적어주어서 내 개인 계정의 모듈 경로를 추가해 주어도 되겠다:
# PERL5LIB 값을 명시해주고
PERL5LIB=/home/gypark/local/perl/lib/perl5:/home/gypark/local/perl/lib/perl5/i386-linux-thread-multi

# 그냥 시스템 펄을 사용하도록
10 0 * * *   /some/script_path

5. screen 위에서 스위칭

ScreenUtility를 실행한 상태에서 그 위에서 perlbrew로 스위칭을 하는 건... 생각처럼 잘 안 된다.

일단 경험상 알아낸 것만 정리하면

6. CGI 스크립트의 스위칭

지금 이 gyparkwiki와 같이 웹을 통해서 실행되는 스크립트를 내 개인 계정의 5.14 위에서 돌게 하려면... shebang 라인에 full path 적어주는 수밖에 없으려나...?

아니면 애초에 너무 무모한 생각인가..?

7. 0.60 버전의 환경 변수 설정 버그

perlbrew 0.60을 bash 위에서 쓰면 환경변수 세팅이 엉망이 되어 버린다.

PATH="/home/gypark/perl5/perlbrew/bin:/home/gypark/perl5/perlbrew/perls/perl-5.16/bin";:...
# 따옴표와 세미콜론이 포함되어 버림

PATH 뿐 아니라 관련된 다른 환경변수들도 마찬가지. 그래서 perl을 실행도 못 시키고, perlbrew도 제대로 동작하지 않고 등등의 문제가 생긴다.

보아하니 0.60으로 바뀔 때, 다른 쉘에서의 문제를 해결하기 위해서 eval 문에 괄호 위치가 바뀐 것 같은데, 이게 bash에서는 문제가 되는 것.

저 링크에 있는 패치를 역으로 적용하든가, 아예 다음과 같이 하여 0.59로 되돌릴 수 있다.
curl -kLO https://t.co/f78pXubFWo ; perl ./perlbrew self-install

그 사이에 0.61이 나왔음. 이 문제는 해결된 걸로 보이니 업그레이드를 해도 되겠다

8. 참고

9. Comments

cpan명령으로 App::perlbrew로 설치해서 perlbrew를 사용한다고 했을때 버젼을 switch하면 아마도 perlbrew는 예전 perl쪽이랑 연결이 유지되거나 링크가 끊기며 그순간 사용불능이 되거나 해서 문제를 일으킬 소지가 많다고 생각되네요.

curl -kL http://install.perlbrew.pl | bash 명령으로 설치해서 단일 파일로 돌아가게 하고 최신버젼 업데이트는
perlbrew self_update 명령을 통해서 하면 문제가 생길 소지가 좀 줄어들 것 같습니다.

정리하면 perlbrew는 cpan명령으로 App::perlbrew모듈을 설치하지말고 웹에서 직접 땡겨서 부트스트리핑하는 단일 패킹된 perlbrew만 쓰자가 되겠네요.
-- aero 2012-2-23 9:26 am

네, 그래야겠더라고요. 겉으로는 차이점을 알아 보지 못해서 고생 좀 했습니다ㅎ
-- Raymundo 2012-2-23 11:26 am

bash에 --login 옵션을 주면 상황에 관계 없이 .bash_profile을 읽습니다만… 애초에 스크립트는 자신에게 필요한 환경 설정은 스스로 하는게 맞습니다. 아니면 다이나믹 라이브러리 패스(LD_LIBRARY_PATH? 시스템에 따라 좀 다릅니다)같은게 바뀐채로 돌아서 엉뚱한 일을 하게 만드는 해킹이 먹히죠. 그런 이유로 suid 걸리면 애초에 스태틱 링크를 하든가 다이나믹 라이브러리 패스를 시스템 차원에서 고정시키는 경우도 있죠.
-- 라슈펠 2012-2-23 1:33 pm

안녕하세요, "bash에 --login 옵션 주는" 게 어느 시점에서 말씀이세요? crontab 에
SHELL=/bin/bash --login
또는
SHELL="/bin/bash --login"
또는
SHELL=/bin/bash\ --login
해 봤는데 아예 전혀 실행이 안 되더라고요.
(이 얘기를 하신 게 아닌 건지 아니면 원래 되던 건데 이것마저 막았다고 봐야 하는 건지)
(그나저나 한 십년 전에 리눅스 사용에 관한 두꺼운 책 다 읽었던 건 하나도 기억이 안 나서 ^^; 계속 도움 받는군요, 감사합니다)
-- Raymundo 2012-2-23 1:54 pm

그냥 crontab에 들어가는 명령을

/bin/bash --login -c <script path/name>

정도로 하시면 될겁니다.
-- 라슈펠 2012-2-23 2:18 pm

아 -c는 빼는게 낫겠군요.
-- 라슈펠 2012-2-23 2:20 pm

꼬박꼬박 콜론 숫자 챙겨서 들여쓰기 하지 않으셔도 되는데요 ^^

실행할 게 쉘스크립트가 아니다보니 -c를 넣어야겠네요. 잘 동작하는 거 확인했습니다. /박수
-- Raymundo 2012-2-23 2:34 pm

근데 .bash_profile 내용에 따라 다르겠지만, .bash_profile 이후에는 아마 script 있는 위치와는 동떨어진 곳에 가 있을 수 있기 때문에, 절대패스가 아니면 안돌거고, 그러면 윗 내용들을 보건대 문제가 될 수도 있겠죠.

아니면 스크립트를 손봐서 interactive shell이 아닌 경우에는 .bashrc를 강제로 읽어본다든가 하는 수도 있긴 하겠죠...

근데 처음 말했던 것처럼 애초에 스크립트에 필요한 환경은 스크립트 안에서 설정하는게 맞아요. 'ㅅ'
-- 라슈펠 2012-2-23 2:34 pm

넵 감사합니다.
-- Raymundo 2012-2-23 2:45 pm

또 하나
perlbrew exec some.pl 는 some.pl 스크립트를 현재 인스톨되어있는 perl들을 다 돌아가며 실행시키는 것 같네요. 어떤 프로그램을 현재 설치된 Perl에 다돌려서 모든 결과를 한번에 보고 싶을때 쓰는 용도인듯....
-- aero 2012-2-24 5:40 pm

악ㅋㅋ 제가 인스톨한 버전이 한 가지 뿐이라서 그걸 착각했군요ㅋㅋ 말씀하신 대로네요.
-- Raymundo 2012-2-25 12:49 am

웹을 통해 실행되는 CGI 스크립트의 경우 쉬뱅 라인에 사용할 perl의 full-path를 적어주는 것이 가장 안전하고 확실한 방법입니다.

그것이 아니라면 cgi를 실행시키는 웹서버 측의 설정 또는 path 경로를 조정해서 해당 디렉터리 하부의 cgi에 대해서는 해당 사용자 펄을 우선 검색할 수 있도록 설정하면 됩니다.

제 경우 버그질라를 perlbrew로 설치한 perl 5.14.2로 실행시키는데 성공했고 첫 번째 방법은 간단히 해결할 수 있었습니다. 그리고 두 번째 방법의 경우 손이 좀 갔는데 아파치 설정을 좀 만져야 해서 번거로웠구요. mod_perl을 사용하지 않는다면 그래도 비교적 간단하게 해결할 수 있답니다. :)
-- keedi 2012-2-28 12:02 pm

그렇군요, 감사합니다~
-- Raymundo 2012-2-28 3:11 pm
이름:  
Homepage:
내용:
 

컴퓨터분류
각주:
1. 3. Twitter:Keedi님께 많은 도움 받았음. 감사합니다.
2. ['모듈설치'페이지의 '주인장의 경우' 섹션] 참고
4. 이 서버에서 수행했던 스크립트를 PC에 가져와서 돌렸더니 동작이 달라졌음
5. 그 반대로 펄은 하위 호환성을 너무 챙겨주는 감이...
6. https://twitter.com/rashper/statuses/172226477813792768 에 의하면 보안상 이유로 막혀 있는 듯?
7. Twitter:nvingTwitter:keedi님 감사합니다

마지막 편집일: 2014-5-30 4:37 pm (변경사항 [d])
2992 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기