@keedi - Seoul.pm 리더, Perl덕후, 거침없이 배우는 펄의 공동 역자, keedi.k at gmail.com
펄을 사용하다보면 CPAN을 사용하는 것은 아주 자연스러운 일입니다. CPAN을 이용해서 다양한 모듈을 설치하고 사용하다보면 어느 순간 지금까지 설치한 모듈의 전체 목록이 필요할 때가 있습니다. 단순한 호기심 때문일 수도 있고, 펄을 새로 설치한 후 필요한 모듈이 없어서 일 수도 있으며, 펄로 만든 서비스를 다른 시스템에 옮기기 위해서 일 수도 있습니다. 지금까지 그렇지 않았다하더라도, 여러분은 현재 시스템에 설치한 모듈의 목록을 확인하는 방법이 머지않아 필요할 것입니다. :)
필요한 모듈은 다음과 같습니다.
직접 CPAN을 이용해서 설치한다면 다음 명령을 이용해서 모듈을 설치합니다.
$ sudo cpan ExtUtils::Install
사용자 계정으로 모듈을 설치하는 방법을 정확하게 알고 있거나 perlbrew를 이용해서 자신만의 Perl을 사용하고 있다면 다음 명령을 이용해서 모듈을 설치합니다.
$ cpan ExtUtils::Install
사실 ExtUtils::Install 모듈은 코어 모듈이므로 따로 설치하지 않고, 펄과 함께 설치된 버전을 사용해도 무방합니다. :)
CPAN의 모듈을 정석으로 설치할 경우 설치하는 각각의 모듈은
설치되는 디렉터리에 .packlist
파일을 생성합니다.
따라서 이 .packlist
파일을 모두 모아 각 파일의 경로와 내용을 참고하면
간단히 설치한 모듈의 전체 목록을 확인 할 수 있습니다.
그러므로 설치한 모듈의 전체 목록을 찾고 싶다면 우선 .packlist
파일을
확보해야 합니다.
당연하지만 .packlist
파일은 모듈을 설치한 디렉터리에 존재하며,
일반적으로 이 디렉터리는 @INC
에서 명시하는 경로입니다.
@INC
의 값은 여러분의 시스템 및 펄 환경에 따라 다릅니다.
@INC
를 확인하려면 다음 명령을 실행합니다.
$ perl -E 'say for @INC' /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.20.1 /usr/local/share/perl/5.20.1 /usr/lib/x86_64-linux-gnu/perl5/5.20 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.20 /usr/share/perl/5.20 /usr/local/lib/site_perl . $
확인해야 할 디렉터리 목록을 확보했으니 이제 .packlist
를 찾아볼까요?
명령줄에서 다음 명령을 실행합니다.
$ perl -MFile::Find -E 'find( sub { return unless $_ eq ".packlist"; say $File::Find::name }, @INC )'
출력되는 .packlist
파일의 전체 경로로 이 값을 이용해
설치한 모듈의 목록을 구해야 합니다.
다만 목록이 꽤 길게 나올텐데 원라이너로 처리하기는 조금 버겁군요.
원라이너를 스크립트로 변경해봅시다.
#!/usr/bin/env perl use v5.20; use strict; use warnings; use File::Find; find( sub { return unless $_ eq ".packlist"; say $File::Find::name; }, @INC, );
.packlist
파일은 /path/to/auto/Foo/Bar/Baz/.packlist
와 같은 식의
경로를 가지는데 .../auto/
뒷 부분부터 /.packlist
앞 부분 까지의
경로에서 /
구분자를 ::
으로 바꾸면 설치한 모듈의 실제 이름입니다.
스크립트를 조금 더 고쳐볼까요?
#!/usr/bin/env perl use v5.20; use strict; use warnings; use Config; use File::Find; my %modules; find( sub { return unless $_ eq ".packlist"; return if $File::Find::dir eq $Config{archlibexp}; my $module = $File::Find::name; $module =~ s{^.*?/auto/(.*)/.packlist}{$1}s; $module =~ s{/}{::}g; ++$modules{$module}; }, @INC, ); say for keys %modules;
이전과 달라진 부분은 다음과 같습니다.
$Config{archlibexp}
디렉터리의 .packlist
파일을 무시함.../auto/Foo/Bar/Baz/.packlist
경로에서 Foo/Bar/Baz
경로 추출/
에서 ::
로 변경설치한 모듈의 목록을 얻는 원리를 설명하다보니 조금 멀리 돌아왔군요. 모듈을 구하고 싶을 때마다 이렇게 스크립트를 짜는 것은 번거롭겠죠. 준비물을 보면서 눈치채셨겠지만, 이미 펄은 코어 모듈로써 ExtUtils::Install 모듈을 제공하며, 이 모듈은 지금까지 설명한 기능을 이미 포함하고 있습니다. 따라서 여러분은 복잡한 부분은 다 건너뛰고 손쉽게 원하는 결과를 얻을 수 있습니다. 명령줄에서 다음 명령을 실행해보세요.
$ perl -MExtUtils::Installed -E 'say for ExtUtils::Installed->new->modules' Acme::AsciiArtFarts Acme::AsciiArtinator Acme::EyeDrops Algorithm::C3 ... CPAN::Meta CPAN::Meta::Check CPAN::Uploader CSS::Tiny $
간단하죠? :)
여러분이 perlbrew를 이용해서 펄 환경을 구축해 쓰고 있다면 더욱 간단한 명령으로 동일한 결과를 얻을 수 있습니다.
$ perlbrew list-modules Acme::AsciiArtFarts Acme::AsciiArtinator Acme::EyeDrops Algorithm::C3 ... CPAN::Meta CPAN::Meta::Check CPAN::Uploader CSS::Tiny $
perlbrew의 list-modules
옵션은 내부적으로
ExtUtils::Installed
모듈을 사용해 설치한 모듈의 목록을 출력하도록
구현되어 있으며 지금까지 살펴본 내용과 대동소이합니다.
# # perlbrew 소스 코드 중 일부 # sub run_command_list_modules { my ($self) = @_; my $class = ref($self) || __PACKAGE__; my $app = $class->new( qw(--quiet exec --with), $self->current_env, 'perl', '-MExtUtils::Installed', '-le', 'BEGIN{@INC=grep {$_ ne q!.!} @INC}; print for ExtUtils::Installed->new->modules;' ); $app->run; }
막상 알고보면 간단하지만 현재 시스템 및 사용 중인 펄 환경에 설치한 모듈의 목록을 구하는 방법을 모르는 경우가 생각보다 많은 편입니다. 대부분의 경우 설치한 모듈의 목록을 구하는 것은 다시 동일한 모듈을 설치해야 할 필요가 (갑자기) 생겼기 때문입니다. 지금까지 알아본 여러가지 방법을 이용하거나 응용하면 손쉽게 모듈의 목록을 확보할 수 있으며 cpan 쉘이나 cpanm을 이용해 새로운 환경에 이전에 설치했던 펄 모듈을 동일하게 설치할 수 있을 것입니다.
Enjoy Your Perl! ;-)
EOT
R.I.P. @am0c
X-mas tree
& Llama
ASCII Art by ASCII Art Farts.
Computer ASCII Art by Chris.com.
Font ASCII Art by TAAG.
Artwork by
Inkyung Park
& Keedi Kim.
Designed by
Hojung Youn
& Keedi Kim.
Articles by
Seoul Perl Mongers.
Edited by
Luzluna Park
& Keedi Kim.
Hosting generously sponsored by
Yuni Kim.
Sponsored by
SILEX.
.-''' __ __ / \/ \/ \ =-_- | \. -____- / \ // /|| '' //| //|| == = == ==