Shell과 Perl의 찰떡궁합

2 minute read

과거 펄 바람

나는 과거에 펄바람이 든 적이 있다. 2013 년도 cocos2d 로 ios 게임을 출시하게 되었는데, 이 때 요청은 우리 다 좋은데 android 도 출시해야하지 않을까? 요청이 있었다.

…………….

미리 말하지만 아시는 분은 알겠지만 cocos2d 는 objective-c 라이브러리였고, 미니게임이지만 해당 게임을 코드는 4천줄 가량되는 규모였다. 해당 라이브러리 거의 그대로 쓰면서 어떻게 안드로이드로 출시할까? 고민했다. cocos2d-x 가 크로스플랫폼으로 동작하고 있었고, 그 당시 해당 라이브러리는 내가 가장 좋아하는 C++ 기반이었다. 처음에는 의욕이 넘쳐 한줄 한줄 컨버팅하기 시작했다. 하지만 사람이라는게 기계적으로 코드 컨버팅을 하다보면 이거 자동화하는 루틴이 몸에 생긴다. 변환 스크립트나 짜볼까? 그래서 무려 objective-c -> c++ 변환 스크립트를 짰다. 그 주인공은 바로 perl!

이미 정규식과 문자열 처리에는 아주 능하다는 소문을 익히 들어 알고 있어서 perl 을 이용해 변환 스크립트를 만들었다. 이 때 이후로 펄은 손대지 않았다.

2020-10-02-224742_1206x808_scrot

내가 짠 코드지만, 펄에 능숙하지 못해서인지 코드가 거의 암호수준으로 느껴진다. 근 7년만에 재회한 코드다.

코드의 가독성은 제외하면 굉장히 빠른 시간안에 나의 목적을 달성하게 해준 언어로 좋은 기억으로 남아있다. 하지만 가독성의 문제로 기억속에 묻혀두고 있었는데 …

현재의 위치

과거의 펄은 요새아덜은 믿지 못하겠지만 python 과 항상 비교되던 스크립트 언어의 선두주자였다.

https://kldp.org/comment/552393#comment-552393 - Perl vs Python 논쟁은 예전부터 있었지만…

https://kldp.org/node/53951 - 파이썬과 펄의 속도 비교

위와 같은 글을 보더라도 파이썬과 자주 비교되던 메이저 프로그래밍 언어였지만 현재는 파이썬에 밀려 언어구실을 제대로 못하고 있다. 지하 어둠의 개발 비밀결사와 같은 단체말고는 거의 요즘엔 관심을 받지 못하고, 실제로 배우고자하는 의지도 없고 이득도 별로 없다.

쉘과의 환상 조합

하지만 아직 대부분 시스템에서는 perl 컴파일러가 기본적으로 제공되고 있고 쉘과의 조합이 매우 막강하여 펄을 깊게 배우진 않더라도 간단히 교양수준으로 배워놓으면 활용도가 매우 크다.

기본적으로 쉘-프로그래밍은 stdin, stdout 을 다루는 작업이라고 볼 수 있는데, linux/unix 에서는 파이프( ) 문자를 이용해서 이 목적을 달성하곤 한다.

예를 들어 process name 이 ksoo 인 프로세스를 모두 종료시키는 스크립트를 짜본다고 가정한다. (pkill 있는거 안다 쫌!!)

먼저 ps aux 로 프로세스 목록을 뽑고 grep 을 통해서 필터링하고 kill -9 으로 종료, 빵!

ps aux | grep ksoo 을 실행해보면

USER PID %CPU %MEM VSZ RSS TTY STAT …

으로 이뤄진 테이블이 출력된다. 우리가 관심있는 필드는 두 번째 PID 다.

ps aux | grep ksoo | awk '{print $2}'

이러면 ksoo 인 pid 가 싸그리 나오게 된다. 그러면 kill -9 pid1 pid2 pid3 ... 형태로 넘겨줘야 하는데 어떻게 하나? 우리의 친구 xargs 를 이용한다.

ps aux | grep ksoo | awk '{print $2}'  | xargs kill -9

이 처럼 쉘-프로그래밍은 stdin/stdout 을 이용하여 작업을 하게 되는데, 여기서 정보처리의 복잡도를 더 늘려보자. ksoo 프로세스이름을 가지는 애들의 TIME 을 분단위로 나타내보자. TIME 은 hh:mm 단위로 나타나고 hh * 60 + mm 으로 표시하면 된다.

자. 어떻게 하나?

ps aux | grep ksoo | awk '{print $10}' | awk -F ':' '{print $1,"___",$2, $1 * 60 + $2}'

위처럼 하면 되지만, awk 의 문서를 찾아봐야 하고, 어떤 경우에는 한줄로 쓰기가 곤란할 정도의 처리를 할 때도 있고, 쉡-프로그래밍을 하기에도 곤란한 경우가 있다. 정규식으로 파싱하고 캡쳐하여 후처리가 필요하다거나…

perl 로 해볼까?

some.pl

while(<>) {
    @s=split(" ");
    @a=split(":", $s[9]);
    print $a[0]*60 + $a[1], "\n";
}

ps aux | grep ksoo | perl some.pl

동작을 확인한 후 이제 oneline 으로 바꿔보자.

여기서 -ne 옵션, perl -ne ‘CODE’ 다음 프로그램과 똑같다.

while (<>) {
    CODE
}

그러면 oneline 으로 고쳐보면,

ps aux | grep usr | perl -ne '@s=split(" "); @a=split(":", $s[9]); print $a[0]*60 + $a[1], "\n"'

정규식을 이용한 방법

ps aux | grep usr | perl -ne '@s=split(" "); $s[9]=~/(.+):(.+)/; print $1*60+$2,"\n";'

마무리 하며 …

펄의 위상은 옛날에 비해 매우 떨어져있지만 쉘-프로그래밍과 찰떡 궁합의 퍼포먼스를 보이며 익혀 놓으면 여러분의 리눅스 생활을 윤택하게 해줄 수 있는 도구가 될거다.

Updated: