2011-05-23

(Perl) perlbrew 를 이용하여 다양한 버전의 Perl을 설치해보자!

CentOS 5.6 에 기본으로 설치되어 있는 Perl 의 버전은 5.8.8 이다. 버전이 낮아도 한참 낮다. 요즘 다른 OS에는 5.10을 기본으로 사용하도록 되어 있으며, 최신 버전은 5.12 이다. 거기에 벌써 5.14 RC 버전까지 나온 상태이다. 이런 구닥다리 버전을 벗어나서 그나마 남들도 쓰는 버전을 쓰려면, 별도로 Perl 을 설치해야 되는데... 직접 소스 파일을 다운로드하여 컴파일/설치 하는 것도 방법이겠지만... 더욱 유연하고 확장성 있는 방법을 소개하고자 한다. 지난번 pythonbrew 를 이용해서 여러 버전의 python 을 설치하는 법을 알려드렸는데, 이것의 원조인 perlbrew 를 이용하면 우리가 원하는 것을 할 수 있다.



  1. 먼저 perlbrew를 설치한다.
    $ curl -L http://xrl.us/perlbrewinstall | bash
    설치를 완료하면 ~/perl5/perlbrew 가 생성된다. 그리고, 여기에 모든 파일들이 들어있다.
  2. .bashrc 에 다음을 추가한다.
    source ~/perl5/perlbrew/etc/bashrc
  3. Perl 5.12.3 설치해보기
    $ . .bashrc
    $ perlbrew install --force perl-5.12.3
  4. Perl 5.12.3 사용해보기
    $ perlbrew use perl-5.12.3
    $ perl -v
    
    This is perl 5, version 12, subversion 3 (v5.12.3) built for i686-linux
    
    Copyright 1987-2010, Larry Wall
    
    Perl may be copied only under the terms of either the Artistic License or the
    GNU General Public License, which may be found in the Perl 5 source kit.
    
    Complete documentation for Perl, including FAQ lists, should be found on
    this system using "man perl" or "perldoc perl".  If you have access to the
    Internet, point your browser at http://www.perl.org/, the Perl Home Page.
  5. Perl 시스템에 설치된 원래 버전 사용하기
    $ perlbrew off
    
    perlbrew is switched off. Please exit this shell and start a new one to make it effective.
    To immediately make it effective, run this line in this terminal:
    
        exec /bin/bash
    
    $ perl -v
    
    This is perl, v5.8.8 built for i386-linux-thread-multi
    
    Copyright 1987-2006, Larry Wall
    
    Perl may be copied only under the terms of either the Artistic License or the
    GNU General Public License, which may be found in the Perl 5 source kit.
    
    Complete documentation for Perl, including FAQ lists, should be found on
    this system using "man perl" or "perldoc perl".  If you have access to the
    Internet, point your browser at http://www.perl.org/, the Perl Home Page.
  6. perl-5.12.3 을 default Perl 로 설정하기
    $ perlbrew switch perl-5.12.3
    Switched to perl-5.12.3





2011-05-17

Ruby : 10MB 이상의 파일중에서 중복된 파일 찾기

아래 코드에서 파일에 대한 MD5SUM 을 구하기 위해서 주석 처리한 부분을 대신 사용할 수 도 있다. 인터넷에서 찾아보면 이렇게 되어 있는 경우가 많은데, 이렇게 하면 메모리를 많이 잡아먹는 문제가 발생한다. 반드시 Digest::MD5.file().hexdigest 를 이용해야만 적은 메모리를 사용하면서 원활하게 동작되니 주의하기 바란다.

10MB 이상의 파일중에서 중복된 파일 찾기
# -*- coding: cp949 -*-
require 'find'
require 'digest/md5'
 
file_list = Array.new
Find.find("C:\\") do |path|
  if File.file?(path) and File.size(path) > 10_000_000
    # digest = Digest::MD5.hexdigest(File.read(path))
    # --> 위와 같이 해도 되지만, 메모리를 많이 잡아먹는다.
    digest = Digest::MD5.file(path).hexdigest
    file_list << digest+"|"+path
  end
end
 
distinct_list = Hash.new(0)
file_list.each do |val|
  (md5, file) = val.split(/\|/)
  distinct_list[md5] += 1
end
 
distinct_list.each do |md5, count|
  if count >= 2
    print "\n["+md5+"]\n"
    file_list.each do |val|
      (md5_2, file) = val.split(/\|/)
      if md5 == md5_2
        print file+"\n"
      end
    end
  end
end


2011-05-14

PHP : 빈 디렉토리 삭제하기

파일서비스를 하다 보면, 불필요하게 비어 있는 디렉토리들이 우후죽순으로 생겨난다. 용량은 얼마 차지하지 않겠지만, 관리상 지저분한 면이 있으니, 깔끔한(?) 성격을 가진 관리자라면 이것 조차도 지우고 싶을 것이다. Windows 에서는 빈 디렉토리를 지울 수 있는 유틸리티를 이용해서 지워도 되고, Unix 계열이라면 find 를 이용해서 지울 수 있다.

다음 PHP 코드를 이용하면, 모든 OS에서 동일하게 빈 디렉토리를 삭제할 수 있다. 같은 일을 하는 코드를 찾아봤지만, 없어서 직접 구현해보았다. 간단하다, 모든 디렉토리를 순회하면서 해당 디렉토리 내에 파일/디렉토리가 있는지 검사해서 아무 것도 없으면, 삭제 대상으로 등록하고, 나중에 한방에 지우도록 한 것이다.


// -----------------------------------------
// 빈 디렉토리 삭제
// -----------------------------------------
$dst_dir  = "C:\\";
// -----------------------------------------
 
function find_empty_folder($dst_dir) 
{
    $result = array();
 
    $i = 0;
    $rdi = new RecursiveDirectoryIterator($dst_dir);
    try {
        foreach (new RecursiveIteratorIterator($rdi, 
            RecursiveIteratorIterator::SELF_FIRST, 
            RecursiveIteratorIterator::CATCH_GET_CHILD) as $path) {
 
            if ($path->isDir()) {
                if(2 == count(scandir($path->__toString()))) {
                    $result[$i++] = $path->__toString();
                }
            }
        }
    } catch(Exception $e) {
        echo "Message: ".$e->getMessage();
    }
 
    return $result;
}
 
 
$list_empty_folder = find_empty_folder($dst_dir);
 
foreach($list_empty_folder as $empty_folder) {
    echo $empty_folder."\n";
    unlink($empty_folder);
}



TABLE, 정말 레이아웃에 쓰면 그렇게 나쁜 것인가?

WEB 2.0 이 대두되면서부터 TABLE 태그로 레이아웃을 짜면 아주 아주 나쁜 행위라고 많은 사람들이 얘기하고 있다. 그런데, 정말로 TABLE 대신 모두 DIV 로 레이아웃을 구성해야만 하는 것인가? 이 것은 절대로 그런 것만은 아니라고 말하고 싶다.

기존의 TABLE 을 이용한 레이아웃은 확실하게 문제가 있었다. 가장 큰 문제점은 디자인을 위해서 심하게 중첩된 TABLE을 사용하여 너무나도 복잡스런 코드를 양산하여 유지보수를 어렵게 만든다는 것이었다. 이 문제를 해결하는 가장 간단한 방법은, TABLE을 중첩시키지 말고 최대한 CSS 를 이용하여 디자인하는 것이다. 굳이 DIV 태그로 대체하지 않아도 된다는 것이다.

물론, TABLE을 이용한 레이아웃에는 이 외에 몇가지 사소한 문제점이 더 있다. http://ilmol.com/wp/2005/06/09/25/ 에서 일몰님이 얘기한 것 만 봐도 DIV로 하는 것이 더 나은 것처럼 보인다. 대부분의 이런 주장들은 웹페이지를 문서의 관점에서 보면 아주 타당하다. TABLE 보다 더욱 다루기 편하고, 빠르고, 유연하다는 것을 인정한다. 문서라고 본다면 CSS를 제거하여도 내용을 파악하는데 문제가 없어야 좋은 웹페이지라고 볼 수 있다.

그러나, 웹은 문서로써의 개념도 가지고 있지만, 어플리케이션으로써 이용되는 경우도 많이 있다. PC에서 동작되는 프로그램, FLEX, Silverlight 를 보면, TABLE 형태의 레이아웃 태그가 지원이 되며, 레이아웃을 위해서 가장 많이 쓰이는 것을 확인할 수 있다. 그렇지만, 여기에서 그런 레이아웃 태그를 사용한 것에 대해서 문제시 하는 경우는 거의 없다.

DIV 태그도 레이아웃을 구현하는데 절대적인 것은 아니다. 아직 브라우저 마다 구현이 다르며, 버그를 가지고 있어서 여러가지 브라우저에서 같게 보이게 하려면 많은 공수가 들어간다.

내가 주장하는 바는,

  1. 디자인에 대한 것은 CSS를 통해서 구현하며,
  2. TABLE 과 DIV의 장단점을 알고, 상황에 맞추어 적절하게 사용하는 것이 좋다.

보통, TABLE을 레이아웃으로 사용하기에 괜찮은 경우는 아래와 같은 상황이 될 것이다.

  1. 어플리케이션 성격이 아주 강하며,
  2. 형태가 자주 변하지 않는 정적인 화면 구조를 갖는 경우

아무래도, DIV와 TABLE을 적절히 섞어 쓰는 것이 좋을 듯 하다. 모두 다 DIV로 하거나, TABLE로만 하는 것은 옳지 않다. 그동안 잘 써온 TABLE을 너무 미워하지 말자. *^^*

또 다른 TABLE 레이아웃 옹호 글로 http://www.flownet.com/ron/css-rant.html 이 있다.

2011-05-11

(Freeware for Business) Viu 2 : 이미지뷰어

대한민국에서 가장 많이 쓰이는 이미지뷰어는 아마도 알씨일 것이다. 그런데 이것이 개인 사용자에게는 무료이지만, 기업 사용자는 돈을 받고 있다는 것을 대부분 모르고 있다. 각 기업의 소프트웨어 담당자들은 이점을 잘 있어야 하며, 불법소프트웨어 단속시에도 알시리즈가 가장 많이 걸린다는 것도 염두해두어야 한다.

그렇다면, 회사에서 개인적으로 쓸만한 이미지 뷰어는 어떤 것이 있을까? 바로 viu2 이다. 홈페이지는 http://www.silentsea.net/viu2/ 이며 첫페이지에서 바로 다운로드 받을 수 있다.



[장점]
  • 단일 실행파일로 설치가 필요 없다.
  • 파일 사이즈가 작다. (1.13MB)
  • 크기가 작은 만큼 상당히 가볍고 빠르게 구동된다. (저사양 PC에 적합)
  • 썸네일 생성도 빠르다.
  • 간단한 편집기능(Rotate, Flip, Resize)을 제공한다. (선택/일괄 수정 가능)
  • 사진에 Comment 를 입력할 수 있다.

[단점]
  • 글쎄... 이정도면 이미지 뷰어로써 충분하다고 보는데...

앞으로 지속적으로 기업에서 사용할 수 있는 Freeware를 소개할 예정이다. 그러니, 불법소프트웨어 사용하지 마시고, 반드시 필요한 프로그램은 구입해서 사용하되, Freeware 로 대체가 가능한 것은 될 수 있으면 Freeware 를 이용하기 바란다.

2011-05-10

PHP : 윈도우 폴더 크기 구하기

PHP에서 윈도우에서 폴더 크기를 구하려면 아래와 같이 한다.  첫번째 방법은 인터넷에서 찾은 방법인데, 테스트해보니 결과값이 나오지 않았다. 그래서, 어쩔수 없이 하위 폴더를 모두 찾아가면서 파일크기를 모두 더해서 폴더의 전체용량을 구하는 것을 새로 만들었다. 전부다 뒤지기 때문에 시간이 좀 걸린다. 대신 윈도우 뿐만 아니라 다른 OS(Linux, BSD 등)에서도 동작한다는 장점이 있긴 하다. ^^


  • 윈도우 폴더 크기 구하기
    function Get_DirByteSize($Dir_Path) 
    {
        $objFs = new COM("Scripting.FileSystemObject"); 
        $objFolder = $objFs->GetFolder($Dir_Path); 
     
        return $objFolder->Size;  // byte 단위 
    }
    인터넷에서 찾은 예제 코드이긴 한데, 테스트해보니 결과 값이 나오지 않는다. ^^;
  • 무식하지만 확실하게 디렉토리 용량 구하는 방법 (OS 상관 없음)
    function Get_DirByteSize($dst_dir) 
    {
        $dir_size = 0;
     
        $rdi = new RecursiveDirectoryIterator($dst_dir);
        try {
            foreach (new RecursiveIteratorIterator($rdi, 
                RecursiveIteratorIterator::LEAVES_ONLY, 
                RecursiveIteratorIterator::CATCH_GET_CHILD) as $path) {
     
                if ($path->isFile()) {
                    $dir_size += $path->getSize();
                }
            }
        } catch(Exception $e) {
            echo "Message: ".$e->getMessage();
        }
     
        return $dir_size;
    }
     
    $dir_size = Get_DirByteSize("C:\\");
    echo "\nC Drive Size : $dir_size\n";

요즘, PHP를 이용해서 웹프로그래밍 외에 여러가지를 해보고 있는데, 상당히 쓸만하다. Perl, Python, Ruby 가 부럽지 않을 정도로 충분히 많은 것들이 갖추어져 있어서, 왠만한 분야에서 거의 쓰일 수 있을 것 같다.

2011-05-07

pythonbrew 를 이용한 여러 버전의 Python 설치

시스템에 설치된 python 의 버전이 낮아서 문제가 되는 경우가 있을 수 있다. 또는 특정 버전의 python 이 필요할 때도 있다. 이 것을 해결해주는 툴이 있는데, 바로 pythonbrew 이다. Ruby 의 rvm, Perl 의 perlbrew 와 같은 것이라고 보면 된다. 이것을 설치하고 간단하게 사용하는 방법을 알아보도록 하자. *^^* 아래는 CentOS 5.6 에서 테스트된 것이다. 다른 OS에서도 잘되리라 믿는다. 아마도 Windows 에서는 안될 것이다. Python 소스를 컴파일해서 설치하기 때문에~~~


  1. 먼저 pythonbrew를 설치한다.
    # easy_install pythonbrew
    # pythonbrew_install
    or
    # curl -kL http://github.com/utahta/pythonbrew/raw/master/pythonbrew-install | bash
    설치를 완료하면 ~/.pythonbrew 가 생성된다. 그리고, 여기에 모든 파일들이 들어있다.
  2. .bashrc 에 다음을 추가한다.
    export PATH=~/.pythonbrew/bin:$PATH
    . ~/.pythonbrew/etc/bashrc
  3. Python 2.7.1 설치해보기
    # . .bashrc
    # pythonbrew install --force 2.7.1
  4. Python 2.7.1 사용해보기
    # pythonbrew use 2.7.1
    # python -V
    Python 2.7.1
  5. Python 시스템에 설치된 원래 버전 사용하기
    # pythonbrew off
    # python -V
    Python 2.4.3


    2011-05-04

    PHP : 10MB 이상의 파일중에서 중복된 파일 찾기

    PHP가 처음에는 웹프로그래밍을 위해서 만들어졌지만, 지금은 CLI 를 지원함으로써, 일반 General Language 로써의 면모도 갖추고 있다. 그러므로, 시스템 관리/일반 어플리케이션 개발 등에도 널리 활용할 수 있다. 필자는 서버 관리를 주로 하고 있으므로, 시스템 관리를 위한 스크립트를 가끔 작성해야 하는데, 이번에는 PHP로 해보았다. 파일서버 관리를 위해서 주기적으로 오래되거나 필요없는 파일들을 삭제해주어야 하는데, 이 중에서도 중복되는 파일을 제거해주는 것이 꽤 효과적이다. 내가 지울수 있는 권한은 없으니, 중복파일 목록을 사용자들에게 주고 직접 지우도록 하면 그나마 쬐끔 용량을 확보하는데 도움이 된다.

    아래는 10MB 넘는 파일중에서 중복된 파일을 찾아서 파일에 결과물을 남기도록 하였다. 기존에 Perl, Python, Ruby 등으로 만들어 놓긴 했지만, PHP로 만들어보니 꽤 훌륭하게 동작한다. ^^ 코드는 그다지 최적화된 것 같지는 않지만, 참고는 할 만 할 것이다.


    // -----------------------------------------
    // 10MB 이상의 파일중에서 중복된 파일 찾기
    // -----------------------------------------
    $limit_size  = 10000000; // 10MB
    $dst_dir     = "M:\\";
    $file_list   = array();
    $result_list = array();
    // -----------------------------------------
     
    $start_time = date("Y/m/d H:i:s", time());
     
    $i = 0;
    $rdi = new RecursiveDirectoryIterator($dst_dir);
    try {
        foreach (new RecursiveIteratorIterator($rdi, 
                                                RecursiveIteratorIterator::LEAVES_ONLY, 
                                                RecursiveIteratorIterator::CATCH_GET_CHILD) as $path) {
            if ($path->isFile() && $path->getSize() > $limit_size) {
                $md5sum = md5_file($path->__toString());
                echo "($i) [$md5sum] : ".$path->__toString()."\n";
                $file_list[$i++] = $md5sum."\t".$path->__toString();
            }
     
        }
    } catch(Exception $e) {
        echo "Message: ".$e->getMessage();
    }
     
     
    foreach($file_list as $key => $value) {
        list($md5, $path) = split("\t", $value, 2);
        if(!isset($result_list[$md5])) { $result_list[$md5] = 0; }
        $result_list[$md5] += 1;
    }
     
     
    $i = 0;
    $fh = fopen("result_samefiles_".date("Ymd").".txt", "w") or die("Can't open file");
    foreach($result_list as $key => $value) {
        if($value < 2) { continue; }
     
        // fputs ($fh, "\n[$key]\n");
        fputs ($fh, "\n[$i]\n");
        ++$i;
        foreach($file_list as $idx => $file) {
            list($md5, $path) = split("\t", $file, 2);
            if($md5 == $key) {
                fputs ($fh, "$path\n");
            }
        }
    }
    fclose($fh);
     
     
    $end_time = date("Y/m/d H:i:s", time());
     
    echo "\nStart Time -> $start_time \n";
    echo "End Time   -> $end_time \n\n";