2008년 3월 14일 금요일

awk 사용하기 - 1

awk는 개발자의 삶을 편안하게 해주는 툴이다. 사용자가 얼마나 창의적으로 사용하는가에 따라서 여러가지 목적으로 사용될 수 있기 때문에, 사용법보다 응용법이 더 중요하다. 우선 사용법이 잘 정리된 사이트를 소개한다.

http://www.4ellene.net/tt/1087


아래는 개인적으로 개발시 많이 사용하는 사용예이다.

make | awk '{for(i=1;i<=NF; i++) print $i }'


큰 규모의 프로그램을 컴파일할 때는 컴파일 및 링크 옵션이 매우 복잡하고 파일 경로가 길 경우 화면에 출력되는 로그의 양이 엄청나다. 따라서 자칫 makefile에 옵션을 잘못 넣어도 이를 찾아내기도 어렵고, 컴파일 에러가 발생해도 바로 문제 위치를 찾기 어렵다. 이럴 때 위와 같이 사용하면 출력되는 로그가 공백을 기준으로 줄바꿈되며 정렬된다.

아래는 위 옵션 이 없이 make했을때의 결과이다.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc -c -DSPIDER_AP -DVER1 -DCOBRA_AP -DAR
5315 -DFREEDOM_AP -ID:/io-pkt/core_networ
king/stage/usr/include -IC:/QNX632/target
/qnx6/usr/include -I../common/include -Ii
nclude -I../../../../src/dk/mdk/client/co
bra/soc_linux/include -c -V3.3.5,gcc_ntop
pcbe -O2 -I. -I../../../include -I../mdk
-I../devmld -DMAUI -I../../../../src/dk/m
dk/client/soc_linux_driver/include -D:/Av
inashWork/AP61_LinuxART_v53b59/releases/l
inuxsrc/src/802_11/madwifi/madwifi/ath -I
D:/AvinashWork/AP61_LinuxART_v53b59/relea
ses/linuxsrc/src/802_11/madwifi/madwifi -
ID:/io-pkt/core_networking/trunk/sys/dev_
nda/ath_hal -DSOC_LINUX -DLinux -DQNX -DM
DK_AP -DARCH_BIG_ENDIAN -DSOC_AP -DENDIAN
_SWAP -I../devlib -I../devlib/ar5210 -I..
/devlib/ar5211 -I../devlib/ar5212 -I../de
vlib/ar2413 -I../devlib/ar6000 -I../devli
b/ar5513 -I../devlib/inis ../../../../src
/dk/mdk/common/linux_hw.c -o ../../../../
src/dk/mdk/client/cobra/soc_linux/obj/lin
ux_hw.o
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


awk를 사용하여 정리하면 다음 처럼 정렬되어 보인다.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc
-c
-DSPIDER_AP
-DVER1
-DCOBRA_AP
-DAR5315
-DFREEDOM_AP
-ID:/io-pkt/core_networking/stage/usr/inc

lude
-IC:/QNX632/target/qnx6/usr/include
-I../common/include-Iinclude
-I../../../../src/dk/mdk/client/cobra/soc

_linux/include

(중략)

-I../devlib/ar5513
-I../devlib/inis ../../../../src/dk/mdk/c

ommon/linux_hw.c
-o
../../../../src/dk/mdk/client/cobra/soc_l

inux/obj/linux_hw.o
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2008년 3월 9일 일요일

종료상태 넘기기 실수담

며칠 전 디바이스의 레지스터값을 읽고 쓰는 작은 프로그램을 하나 포팅하였다. 타겟 환경은 QNX라는 유닉스 계열의 임베디드 OS였는데, 포팅이 끝난 후 프로그램의 동작 방식을 조금 수정해야 할 일이 생겼다. 원래 프로그램은 읽은 레지스터 값을 화면에 출력하고 종료하는 형태로 실행되는데, 다른 프로그램으로 읽은 레지스터 값을 넘겨주고 종료하도록 동작 방식을 바꾸어야 했다. 부모 프로그램에서 spawn( fork + exec를 합쳐놓은....)을 사용하여 레지스터 읽는 프로그램을 실행하고... 읽은 레지스터 값을 어떻게 받아올까를 잠시 고민했다. 4바이트 레지스터값을 넘기기 위해서 IPC를 사용하기가 귀찮아 간편한 방법을 고민하던 중 exit를 사용하여 프로세스 종료상태를 넘기는 대신 읽은 레지스터값을 넘기는 방법을 생각하기에 이르렀다. QNX에서 제공하는 spawn이라는 API는 P_WAIT옵션을 주면 실행된 자식프로세스가 끝날 때까지 block되어 있다가 호출한 프로세스에게 종료 상태값을 return하는 기능이 있었다. exit() API 문서에도 exit의 인자로 int형으로 명시되어 있어 spawn과 exit를 사용히면 4바이트 레지스터 값을 넘기는데 별 문제가 없어보였지만, 실제로는 잘 동작하지 않았다. 레지스터의 값이 255 이상일 경우에 읽은 레지스터 값이 종료 상태값(echo $?로 확인 가능)으로 넘어오지 않는 것이었다. exit가 int형 파라메터를 가지지만 실제로 unix계열의 OS에서 프로세스 종료 상태는 0~255사이의 값만 가진다는 것을 나중에야 알았다. (혹시 특정 계열 OS에서 255이상을 종료 상태값으로 가지는 환경이 있으면 알려주시기 바랍니다.)