구글 번역기의 읽기 버튼을 조금 활용하여, 간단한 TTS를 해주는 스크립트 입니다. 구글 번역기는 번역된 글을 mp3로 만들어주는 훌륭한 기능을 제공하지요. 따라서, 리눅스에 mpg321 패키지가 제공하는 mpg123 유틸이나, Mac의 afplay를 이용하여 명령행으로 전달되는 문자열을 읽어주게 됩니다.
./play_tts.sh "안녕하세요? 쿨엔!"
만약 영어로 하려면,
TTSLANG=en ./play_tts.sh "How are you? Coolen?"
이런식으로 사용하면 되지요.
이 기능은 소스 커밋하면 목소리로 알려주기 기능의 연장선상에서 진행되었습니다.


play_tts.sh


신고
크리에이티브 커먼즈 라이선스
Creative Commons License
소스 컴파일이 되지 않는 바이너리 혹은 스크립트 수준의 패키지를 위한 rpm build utility 입니다. 만들어 쓰던것을 공유해보고자
 http://code.google.com/p/rpmwand/
위에 둥지를 하나 틀어, rpmwand 라는 이름으로 올렸습니다.
사용방법은 간단합니다.

초기화

$ rpmwand init sample
* Created skeleton directory: 'sample-skel'
* Created file list: sample-files.txt
  Please edit sample-files.txt
* Created spec input file: sample.spec.in
  Please edit sample.spec.in
  Fix TODO values
rpmwand 는 크게 두가지 명령으로 구성되어 있습니다. 'init' 명령과 패키지 이름을 주면 두 개의 파일과 한 개의 디렉토리가 생성됩니다. rpm 빌드용 spec file과 간단한 skeleton root 디렉토리, 그리고, skeleton에 들어간 file list가 들어 있는 파일하나가 생성됩니다.

빌드

$ rpmwand build sample
 * Package name : sample
 * Version      : 1.0.0
 * Release      : 1
--------------------------------------------------------------------------
* Making tarball(sample-1.0.0.tar.gz) for rpm build...
* Tarball(sample-1.0.0.tar.gz) is assumed containing 'sample-1.0.0' directory as the first child item
* Cloning 'sample-skel' directory to 'sample-1.0.0'
* Check if there is custom packaging script (sample-setup.sh)
  skip running: bash sample-setup.sh /home/pynoos/rpmwand/sample-1.0.0
* Tarring 'sample-1.0.0.tar.gz' from 'sample-1.0.0'
--------------------------------------------------------------------------
* Now, building rpm....
Building target platforms: noarch
Building for target noarch
Executing(%prep): /bin/sh -e /home/pynoos/rpmwand/faked-root.19231/tmp/rpm-tmp.83533
+ umask 022
+ cd /home/pynoos/rpmwand/faked-root.19231/
+ true ==================================================================================
+ true 'BEG Build preprocess'
+ true 'END Build preprocess'
+ cd /home/pynoos/rpmwand/faked-root.19231
+ rm -rf sample-1.0.0
+ /bin/gzip -dc /home/pynoos/rpmwand/sample-1.0.0.tar.gz
+ tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd sample-1.0.0
++ /usr/bin/id -u
+ '[' 503 = 0 ']'
++ /usr/bin/id -u
+ '[' 503 = 0 ']'
+ /bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ true ==================================================================================
+ true 'BEG Setup'
+ true 'END Setup'
+ exit 0
Executing(%build): /bin/sh -e /home/pynoos/rpmwand/faked-root.19231/tmp/rpm-tmp.83533
+ umask 022
+ cd /home/pynoos/rpmwand/faked-root.19231/
+ cd sample-1.0.0
+ true ==================================================================================
+ true 'BEG Build'
+ echo 'BUILDROOT: /home/pynoos/rpmwand/faked-root.19231'
BUILDROOT: /home/pynoos/rpmwand/faked-root.19231
+ echo 'PACKAGE-NAME: sample'
PACKAGE-NAME: sample
+ echo 'PACKAGE-VERSION: 1.0.0'
PACKAGE-VERSION: 1.0.0
+ echo 'PACKAGE-RELEASE: 1'
PACKAGE-RELEASE: 1
+ true 'END Build'
+ exit 0
Executing(%install): /bin/sh -e /home/pynoos/rpmwand/faked-root.19231/tmp/rpm-tmp.83533
+ umask 022
+ cd /home/pynoos/rpmwand/faked-root.19231/
+ cd sample-1.0.0
+ true ==================================================================================
+ true 'BEG Installation'
+ /bin/cat
+ true 'END Installation'
+ make prefix=/home/pynoos/rpmwand/faked-root.19231/usr exec_prefix=/home/pynoos/rpmwand/faked-root.19231/usr bindir=/home/pynoos/rpmwand/faked-root.19231/usr/bin sbindir=/home/pynoos/rpmwand/faked-root.19231/usr/sbin sysconfdir=/home/pynoos/rpmwand/faked-root.19231/etc datadir=/home/pynoos/rpmwand/faked-root.19231/usr/share includedir=/home/pynoos/rpmwand/faked-root.19231/usr/include libdir=/home/pynoos/rpmwand/faked-root.19231/usr/lib libexecdir=/home/pynoos/rpmwand/faked-root.19231/usr/libexec localstatedir=/home/pynoos/rpmwand/faked-root.19231/var sharedstatedir=/home/pynoos/rpmwand/faked-root.19231/usr/com mandir=/home/pynoos/rpmwand/faked-root.19231/usr/share/man infodir=/home/pynoos/rpmwand/faked-root.19231/usr/share/info install
I am FAKE Makefile install target. Do you see me?
+ true ==================================================================================
+ true 'BEG make install'
+ true BUILDROOT:/home/pynoos/rpmwand/faked-root.19231
+ /bin/rm -rf /home/pynoos/rpmwand/faked-root.19231/sample-1.0.0/Makefile
+ mv /home/pynoos/rpmwand/faked-root.19231/sample-1.0.0/etc /home/pynoos/rpmwand/faked-root.19231/sample-1.0.0/usr /home/pynoos/rpmwand/faked-root.19231
+ true 'END make install'
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip
+ /usr/lib/rpm/brp-strip-static-archive
+ /usr/lib/rpm/brp-strip-comment-note
Processing files: sample-1.0.0-1
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/pynoos/rpmwand/faked-root.19231
Wrote: /home/pynoos/rpmwand/RPMS/noarch/sample-1.0.0-1.noarch.rpm
Executing(%clean): /bin/sh -e /home/pynoos/rpmwand/faked-root.19231/tmp/rpm-tmp.27064
+ umask 022
+ cd /home/pynoos/rpmwand/faked-root.19231/
+ cd sample-1.0.0
+ true ==================================================================================
+ exit 0
--------------------------------------------------------------------------
 * RPM build done...
 * Check..
/home/pynoos/rpmwand/RPMS/noarch/sample-1.0.0-1.noarch.rpm
위 명령은 'build' 인데 인자를 추가로 version, release, architecture를 갖습니다. 이 명령으로 spec.in을 spec으로 만들고, file-list를 읽어서 rpm을 만드는데 사용합니다.

이렇게 간단한 두 명령으로 일단 sample-1.0.0-1.noarch.rpm 파일이 만들어집니다.

실제 사용을 위해서는 init 명령에 의해 생성된 skeleton root에 원하는 파일을 추가하고, 설치 목록 파일(file-list.txt)을 수정하여 build 명령을 주면 됩니다. 만들어지는 spec.in 파일들을 직접 열어서 수정할 수 있고, 수정하면 전문적으로 사용할 수도 있는 구조로 되어 있으므로, 처음 배우시는 분들에게 도움이 될 것입니다.

참고로, 저희 팀 내부에서는 이 유틸리티의 전신이 되는 툴을 사용하여 php 배포용 rpm을 만들어 사용합니다.
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
  1. jeppy 2010.04.28 14:06 신고

    download cnt 뿐만이 아니라 이 글의 comment 수도 역시나.. -_-;;
    rpmwand 쵝오~ ! fanclub 만들까요? -_-;;

요즘 프로그램 배포시 코드 사인을 하는 문제에 대해서 공부하고 있습니다.

"사용자 소프트웨어의 안전한 배포를 위한 Code Signing 기술 연구" 라는 좋은 글이 있군요.

MS-Windows 용으로 알아보니, signtool.exe 라는 프로그램이 signcode.exe를 대치하여 만들어진것까지 확인하였습니다. Microsoft SDK 를 설치하니 하위 디렉토리에 존재하더군요.

Linux에서도 윈도우용 프로그램에 대해 서명할 수 있는 툴이 아래와 같이 존재합니다.

http://sourceforge.net/projects/osslsigncode/

재밌는 세상입니다.
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
참고:
http://www.google.com/search?q=proc_usb_info.txt&btnI=
http://www.linux-usb.org/usb2.html
http://www.usb.org/developers/docs/EH_MR_rev1.pdf
http://www.os2warp.be/index2.php?name=usbreview

/proc/bus/usb/devices 라는 파일은 현재 꽂혀있는 USB 관련 장치들을 보여주는 파일이다.
(/proc 은 가상의 파일 시스템이고 bus 는 말단의 장비들을 꽂을 수 있는 도로와 같은 것이다)

내가 가지고 있는 2002년 정도에 지급받은 PC에서 위 파일 내용을 살펴보면,

$ cat /proc/bus/usb/devices

T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.17-1.2139_FC4 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1f.4
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.17-1.2139_FC4 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1f.2
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

사실 아무것도 설치되지 않은 상황에서 두 개가 보인다. USB는 하나는 호스트가 되고 하나는 장비가 되어 연결되는 상하관계가 있는 계층 구조를 이루고 있는데, 위 내용의 "S:" 라인을 보면 호스트를 제어하기 위한 "UHCI Host Controller", 즉, 호스트 컨트롤러가 하나의 장비로 취급되어야한다는 스펙에 의해 보이는 것이다.

맨 윗줄에 나오는 "T:" 는 Topology, 즉 현재 위치를 말해주는데, 첫줄을 풀어서 설명하자면,

T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2


Topology:
버스번호=02
레벨=00
부모장치번호=00
물리적 포트 번호=00
순서(Cnt)=00
장치번호=1
스피드=1.2Mbps
최대꽂을수있는장비개수(child)


위 두 장비의 차이는 버스번호, SerialNumber 인데, 이로써, 서로 다른 값을 가지는 버스가 두 개인 것을 알 수 있다. 그리고 각각은 최대 두개씩 장비를 꽂을 수 있는 것이고, 따라서 4개까지 지원되며 각각의 최대 속도는 12Mbps이다.


현재 USB2.0까지 나온 상황에서 속도는 1.5Mbps (USB1.0), 12Mbps(USB1.1), 480Mbps(USB2.0) 이다. 속도는 Spd 항을 봐서도 알 수 있지만, Product 에 보면 UHCI라고 되어 있는데, 이는 Universal host controller interface라는 것이고, Open host controller interface(OHCI)와 더불어 12Mbps (USB1.1)까지 지원한다. 호스트 컨트롤러의 버전은 "D:" 항 장치 설명에서도 Ver=1.10 으로 확인 할 수 있다.

USB 구성 을 나타내는 "C:" 는 "*"이 하나 붙어 있으며, 이 이하는 USB 를 사용하는 방식에 대한 기술이다. 나중에 다시 설명하기로 하고, 척 보았을 때 "*" 을 기준으로 위까지만 하드웨어적인 것이라 생각해 두자.



요즘 받은 새로운 장비를 한 번 살펴본다.


T: Bus=04 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.2
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=03 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.1
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc=118/900 us (13%), #Int= 1, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.0
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 7 Spd=1.5 MxCh= 0
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=055d ProdID=0001 Rev= 1.00
S: Manufacturer=SAMSUNG
S: Product=USB SEM-DT35
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 Driver=usbhid
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms

T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 6
B: Alloc= 0/800 us ( 0%), #Int= 1, #Iso= 0
D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 ehci_hcd
S: Product=EHCI Host Controller
S: SerialNumber=0000:00:1d.7
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=256ms


몇가지 주목할 만한 것이 있는데, 여기에는 키보드가 하나 꽂혀있다.
잘보니 삼성키보임을 알 수 있고, 실제 103키 아주 단순한 키보드가 꽂혀있다.
그리고, 버스가 4개나 되는 것을 보아 상당히 많은 포트를 꽂을 수 있는 머신이다.
버스 중에서 01번은 EHCI(Enhanced Host controller interface) 임을 알 수 있는데, 이것이 USB2.0을 지원하는 포트이다.
버전 설명을 봐도 1.1 -> 2.0 으로 바뀐 것을 알 수 있다.
속도(Spd)도 480Mbps이고 최대 꽂을 수 있는 장비의 수(MxCh)는 6 개나 된다.
상당히 긴 리스트에서 HCI와 일반 장비를 쉽게 구별하는 방법은 레벨(Lev)이다.
레벨은 트리구조로 꽂혀지는 USB 호스트, USB 허브, USB 장비들의 단계를 나타내는데,
USB가 정한 최대 레벨은 5 단계이므로 04까지 가능하다.

저 키보드의 디바이스 번호를 보면 7이고, 상위 디바이스(Prnt)는 01, 즉 HCI 컨트롤러임을 알 수 있다. 그리고 그 키보드에는 MxCh=0 인것을 보아 아무것도 더 꽂을 수 없는 말단 장비임을 알 수 있다. 디바이스 번호는 꽂을 때 임의로 할당하는 식별 번호이므로, 꽂았다 뺐다를 반복하면 같은 장치라도 계속 바뀌게 된다. 7 이라는 숫자를 크게 의식하지 말자.

호스트 컨트롤러의 두번째 줄인 "B:" 는 Bandwidth를 나타내는데, USB1.1까지는 최대 90.0%(900), USB2.0은 최대 80.0%(800) 를 사용한다고 보고 현재 사용중인 대역폭을 나타낸다. Bus 02 번의 대역폭은 다른 Bus 와 달리 어느정도 사용중이며 이것은 키보드 때문에 그렇게 나타난다. #Int, #Iso 는 전송 방식에 따른 사용량을 나타내는 것이며, 인터럽트(interrupt) 방식인지 캠 같은 손실 가능한 데이터(isochronous mode)의 전송량을 알 수 있다.



지극히 개인적인 취미로 다음과 같이 구성해 보자.

위의 장비에 Dell 모니터에 있는 USB Hub를 꽂고 그 USB Hub에 내 SKY IM-7400 핸드폰을 꽂아 보자. 핸드폰을 컴퓨터와 연결하는 장비가 있어야 가능하다. (대개 살 때 주지 않나?)



T: Bus=04 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.2
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=03 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.1
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc=118/900 us (13%), #Int= 1, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.0
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 7 Spd=1.5 MxCh= 0
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=055d ProdID=0001 Rev= 1.00
S: Manufacturer=SAMSUNG
S: Product=USB SEM-DT35
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 Driver=usbhid
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms

T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 6
B: Alloc= 0/800 us ( 0%), #Int= 1, #Iso= 0
D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 ehci_hcd
S: Product=EHCI Host Controller
S: SerialNumber=0000:00:1d.7
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=256ms

T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 13 Spd=480 MxCh= 4
D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=02 MxPS=64 #Cfgs= 1
P: Vendor=04b4 ProdID=6560 Rev= 0.0b
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=01 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=256ms
I: If#= 0 Alt= 1 #EPs= 1 Cls=09(hub ) Sub=00 Prot=02 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=256ms

T: Bus=01 Lev=02 Prnt=13 Port=00 Cnt=01 Dev#= 14 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=02(comm.) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=10a9 ProdID=3197 Rev= 0.00
S: Manufacturer=SK Teletech Co.
S: SerialNumber=Serial Number
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=cdc_acm
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=32ms
I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_acm
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=(none)
E: Ad=84(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=04(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms

Level 2 짜리가 생겼다. 두 번째 단계에 달려 있는 USB 장치라는 뜻이된다. 그 SK Teletech Co. 출신 장비는 14번을 할당 받았으며, 13 번 장치에붙어 있다. 장비 번호 13번은 또다른 허브임을 알 수 있다. 그런데, 그 허브는 "S:" 항이 없는 약간은 괴상한 놈이다. 나야 Dell 모니터에 붙어 있는 것을 알 수는 있지만, 저건 전혀 나오지 않는다. 대충만들었나? 그 허브는 MxCh는 4인 것을 보면 4 개를 꽂을 수 있는 것인데, 실제로 포트가 왼쪽에 두개 나와 있고 아래로 두개가 나와 있다.

이 허브는 하나의 interface에 altanate을 두어 0, 1로 구별하고 있다.



정리하자면,

  1. USB 장치들은 Tree 구조로 접속이 되어 있고(Lev, Prnt, Dev#),
  2. 각 장치들은 버전에 따른 속도가 달라지며 (Ver, Spd, Alloc)
  3. hub 장치들은 붙을 수 있는 장치 수가 0 보다 크며(MxCh)

이상으로 /proc/bus/usb/devices 에 기술되어 있는 USB 장치들의 기괴한 목록을 대충 살펴보았다. 다음에 기회가 되면 지금까지 설명하면서 빠진 것을 통해 얻을 수 있는 지식을 정리해보고자 한다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License
  1. 구차니 2008.08.28 11:36 신고

    좋은내용 잘보고 갑니다~

이른바 유틸리티라는 프로그램들이 있다. 이것들은 간단한 기능만을 하는 프로그램들을 말하는데, 전통적인 Unix에는 정말이지 잡다한 유틸리티들이 있다.

예를 들면, "y" 라는 프로그램은 단지 화면에 y를 한 줄에 하나씩만 출력할 따름이며, "true" 라는 프로그램은 항상 정상종료만하는 프로그램, "false"라는 프로그램은 항상 오류 종료만하는 프로그램이다.

이런 유틸리티는 처음 나올때부터 조금씩 진화에 진화를 거듭하게 되고, 때에 따라 개발자가 중도 포기하면, 다른 사람이 이어가거나 아니면 아예 명령어 구문만 같은 다른 프로그램을 만들기도 한다.

따라서, 다양한 버전의 같은 일을 하는 유틸리티가 존재하는데, 그 중 GNU에서 다시 만들어 배포하는 유틸리티들에 대한 얘기를 해보고자 한다.

GNU에서 배포하는 것 들은 기본적으로 긴 옵션을 가지고 있다.
또 이들이 배포하는 것은 --version 과 --help 옵션을 항상가지고 있다.

그리고, 상당히 쓸모 없을 것 같은 이런 긴 옵션들이 너무나, 정말 많다. Linux의 man page에서 이들 옵션에 압도당할 수 있는데, 아마 대부분 그런 긴 옵션에 대해서 거부감을 가지고 자세히 읽지 않는 습관이 들었을 것이다. 이 옵션들은 같은 뜻의 한 글자 옵션이 있기도 하고, 없기도 하다.

내가 보기에 이들 옵션들은 해커기질이 있는 사람들이나 사용할 것 같은데, 예를들어:

grep --mmap -w HOJIN *.txt

라는 명령을 예로 들어 보자. 설명서를 보니 가능하면 메모리 매핑을 해서 파일을 열란다. 이런 확장된 옵션들이 가지고 있는 것은 우리에게 많은 상상력을 불어 넣어준다.

왜? 메모리 맵을 사용하여 열까? 검색할 때, 더 빠르다는 뜻인가? 또, 왜 "가능하면"인가? 메모리 맵이 안되는 파일도 있다는 말인가?

또 다른 옵션을 보자.

$ ls --full-time

-rw-rw-r-- 1 pynoos pynoos 311 2004-06-11 12:34:00.000000000 +0900 AUTHORS
-rw-rw-r-- 1 pynoos pynoos 5 2006-01-05 11:20:56.000000000 +0900 BUILD_NUMBER
-rw-rw-r-- 1 pynoos pynoos 57 2004-06-11 12:34:00.000000000 +0900 COPYING


--full-time 옵션은 ls 명령으로 하여금 시간을 아주 고정폭으로 출력해준다. 그런데 소수점 이하의 초단위가 모두 0 이다. full-time format이 원래 초 이하까지 보여주는 것일까? 아니면 file system에 따라서는 마이크로초까지 저장하는데 내가 사용하는 것만 유독 초까지만 저장되어서 그런 것일까?

위 질문들에 대한 답은 하지 않겠지만, 이와 같이 한번도 사용하지 않은 옵션들을 통해서 설계의 철학을 엿볼 수 있는 질문들을 던져보는 것은 사실 정*말* 중요한 습관 중의 하나이다.

아는 것과 보는 것만 가지고 상상할 수 있는 우리들에게 보는 것에 노출이 된다는 것은 상상을 통한 영역 확장의 좋은 길 아닌가...!

아무거나 보는 습관을 갖는 것이 경험을 통해 아는 것보다 천 배 중요하다.
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

+ Recent posts