'분류 전체보기'에 해당되는 글 124건
- 2007.12.06 replaceAll 구현
- 2007.12.05 java 에서 unsigned int ( byte의 값을 int로 변환)
- 2007.12.05 텍스트 박스 포커스 다음 입력칸으로 자동 이동
- 2007.12.04 emul game site
- 2007.12.02 Windows XP OEM 설치 CD
- 2007.11.30 autohotkey를 이용한 UDF버튼 필요없는 사용자버튼 매핑
- 2007.11.29 dllexp
- 2007.11.28 jar
- 2007.11.26 unix 에서 find 용법
- 2007.11.24 olly debug plugin
replaceAll 구현
java sdk 1.3 이하에서는 replaceAll이 구현되어 있지 않다.
public static String replaceAll( String source, String toReplace, String replacement )
{
int idx = source.lastIndexOf( toReplace );
if ( idx != -1 )
{
StringBuffer ret = new StringBuffer( source );
ret.replace( idx, idx+toReplace.length(), replacement );
while( (idx=source.lastIndexOf(toReplace, idx-1)) != -1 )
ret.replace( idx, idx+toReplace.length(), replacement );
source = ret.toString();
}
return source;
}
java 에서 unsigned int ( byte의 값을 int로 변환)
그런 문제가 발생한다면 아래와 같은 식으로 해주시면 됩니다.
int val = myByte < 0 ? ( Byte.MAX_VALUE + 1 ) * 2 + myByte : myByte;
코드를 보시면 왜 저렇게 써야하는지는 이해를 할 수 있으리라 보네요.
log 의 경우에도 이런식으로 하시면 될것 같구요, 그리고 특별히
Byte, Integer, Long 등의 래퍼클래스의 MAX_VALUE나 MIN_VALUE를 넘지 않는 한은
특별히 신경쓸 이유도 없습니다.(당연하겠지만...)
저도 정확히는 알 수 없습니다만, 자바에서는 자체적으로 BigDecimal 등을 이용해서
C보다 더 큰 숫자를 표현할 수 있는 방법을 제공해 주기 때문에 굳이 C처럼
unsigned 를 지원할 필요가 없다고 생각한게 아닐까요? 라는 생각을 해봤습니다.
텍스트 박스 포커스 다음 입력칸으로 자동 이동
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr" />
<title>무제 문서</title>
</head>
<script>
//다음 칸으로 이동
function moveFocus(num,here,next){
var str = here.value.length;
if(str == num)
next.focus();
}
</script>
<body>
<FORM METHOD='POST' NAME='modify' ACTION=''>
<table width="921" border="1" cellspacing="0" cellpadding="0">
<tr>
<td width="917">
<input type="text" name="gve_date_from" value="20070401" SIZE='9' onFocus="this.select()" maxlength=8 onKeyPress="onlyNum()" onKeyUp="moveFocus(8,this,this.form.gve_date_to);"> ~
<input type="text" name="gve_date_to" value="20070401" SIZE='9' onFocus="this.select()" maxlength=8 onKeyPress="onlyNum()">
1. 마우스 텍스트 박스 클릭하면 전체 선택. 2. 8자리 입력하면 자동으로 다음 텍스트 박스로 커서 이동.
</td>
</tr>
<tr>
<td>
<INPUT TYPE='text' NAME='regnum1' SIZE='6' MaxLength='6' onKeyUp="moveFocus(6,this,this.form.regnum2);"> -
<INPUT TYPE='text' NAME='regnum2' SIZE='7' MaxLength='7' >
1. 주민번호 앞자리 6자리 입력 후 다음 입력칸으로 이동.
</td>
</tr>
</table>
</form>
</body>
</html>
Windows XP OEM 설치 CD
대부분의 노트북에는 OEM 버전이 설치되어 있고 밑바닥을 보면 OEM 버전의 CDKEY 정품 라벨이 붙어 있다.
지점의 영업사원들이 갖가지 제조사의 노트북을 사용하는데 사용상의 문제가 발생하면
손을 보다가 보다가 결국 WINDOW를 설치하는 경우가 흔하다.
이 때 사용자가 노트북 구입시 받은 이미지 복구 CD나 정품 설치 CD(OEM용)를 가지고 있으면 문제될 것이 없는데 CD가 없을 경우 CDKEY는 있는데 설치를 못 하는 경우가 있다.
본사에서 구할 수 있는 건 볼륨 라이센스 버전이라 OEM 버전의 CDKEY를 가진 노트북에 설치해 주면 문제의 소지가 있어 CDKEY를 가지고 있음에도 차후 정품 인증 문제를 걱정하여 설치해 주지 못 하고 A/S센터로 보낸다. 물론 정품 인증이야 크랙하는 다양한 방법이 있겠지만 회사에서 업무상으로 깔끔하게 처리해 주기 위해 그런 편법을 사용하기에는 무리가 있다. 다행히 무상 A/S 기간 내라면 괜찮지만 기간이 지난 제품은 고스란히 사용자의 주머니에서 나가게 되어, 개인적으로 참 불합리하다고 생각이 들었다.
그래서 오늘 OEM 버전의 XP HOME 버전과 PRO 버전의 설치 CD를 구하고자 했는데 참으로 쉽지가 않다. 게다가 하나의 OEM 이미지를 구한다 해도 그게 각각의 제조사 OEM CDKEY로 입력 후 설치 진행에 문제가 없을지도 의문이다. OEM용 설치CD라면 아무 제조사 PC에나 다 설치가 가능하려나?
물론 CDKEY는 해당 제조사 PC용으로 말이다.
어디서 구했는지 기억은 안 나지만 OEM PRO 버전을 내 회사 삼성 노트북에 설치하고 있는데
설치가 잘 진행되고, 예전에 혹하여 적어 두었던 HP OEM용 CDKEY로 입력해서 일단 다음 화면으로 넘어가는 데에는 성공했다. 다 설치되어 윈도우 업데이트가 어떻게 될지 내일 해봐야겠다.
정보를 찾다가 WINDOWS XP 설치 과정을 전부 캡쳐하여 올린 글이 있어 링크를 남긴다.
나중에 윈도우 설치에 대해 묻는 사람이 있으면 이 글을 출력해서 따라하라고 하면 편할 듯하다.
http://kin.naver.com/open100/db_detail.php?d1id=1&dir_id=102&eid=3ag0fzZzdQ/LQqb1VC8n0sHY4Vap2TkP
좋은 정보 추가 - WinXP 설치시 OEM, Retail, Volume License 키 정하기
휘사모
요점 정리하자면,
i386 폴더의 setupp.ini 파일 내용 중,
Pid=55663OEM
이 부분이 cd 종류와 cdkey 종류를 구분한다.
앞의 다섯자리 55663 은 cd의 기능 종류 구분, 뒤의 세자리 oem은 cdkey 종류 구분
Retail키: 000 혹은 335
OEM키: oem
Volume License키: 270
그러므로 해당 cd의 원래 기능은 그대로 설치하면서 cdkey 종류만 바꾸려면
앞의 5자리는 그대로 놔두고 뒤의 세자리 숫자만 종류에 맞게 변경 후 cd를 만들면 된다
autohotkey를 이용한 UDF버튼 필요없는 사용자버튼 매핑
autohotkey 키매핑프로그램 상당히 유용한데 잘 안쓰시는지 저번에 올린건 반응이 없네요.. ㅠ.ㅜ
그래서 좀더 유용한거 다시~ ㅎㅎ
참고로 전 삼성 Q1울트라 N101 모델 사용하고 있습니다.
울트라 사용자들은 상당 UDF버튼을 눌러 각 그룹별로 사용자키에 키들을 할당해서 쓰는데
이게 인터넷, 영화, 게임 각각 설정해놓고 할때마다 UDF 버튼을 눌러 항목을 바꿔줘야 하니 상당히 불편하죠.
영화보는중 되감기 누르려는데 키설정 안되어있으면 멈춰서 윈도우나가서 바꾸고 다시 들어오고..
그래서 이래저래 만들어봤습니다.
설정 바꾸는것 없이 그냥 누르면 인터넷이냐 영화냐등등에 따라서 원하는 값으로 할수있습니다.
다시 말해 인터넷할땐 아래버튼이 스크롤다운인데 영화볼때 볼륨다운이 되는거죠.
내용이 길으니 그냥 천천히 읽어보세요.
===============================================================================================
SC178 up :: // 다이얼키버튼입니다.
Run, C:\WINDOWS\system32\osk.exe // 누르면 윈도우자체내장 화상키보드 실행합니다.
return // 원래있는 다이얼키가 편하시면 삭제요망
SC11A :: // avs 버튼입니다.
Run, C:\Program Files\The_KMPlayer\KMPlayer.exe // 누르면 kmp플레이어 실행합니다. 각자 경로 바꿔주세요.
return // 역시 원치않으시면 삭제
@::Esc // @ 버튼 누르면 esc 로 작동합니다.
-::Lwin // - 버튼 누르면 윈도우키로 작동합니다.
// 버튼 특성인지 연계동작은 안됨..
// 다른걸로 바꾸시거나 원치않으시면 삭제
^Numpad0::Send,{F10} //숫자키상태에서 컨트롤키와 1을 누르면 F1로 동작합니다.
^Numpad1::Send,{F1} //마찬가지로 컨트롤+2는 F2, 컨트롤+3은 F3..
^Numpad2::Send,{F2} //이건 뭐 쓰지않으면 키 자체에는 영향이 없으니까
^Numpad3::Send,{F3} //그냥 나둬도 좋으실듯..
^Numpad4::Send,{F4} //Send뒤에 다른 명령어 넣으시는것도 좋으실듯.
^Numpad5::Send,{F5}
^Numpad6::Send,{F6}
^Numpad7::Send,{F7}
^Numpad8::Send,{F8}
^Numpad9::Send,{F9}
#IfWinActive, ahk_class IEFrame //여기가 중요
#G::Send,{WheelDown} // IEFrame 이라는게 인터넷입니다. 웹마도 같더군요.
#H::Send,{Browser_Forward} // 활성창이 인터넷이면 각 버튼별로 할당된 값 실행
#J::Send,{WheelUp} // 앞으로, 뒤로, 휠다운, 휠업등
#k::Send,{Browser_Back}
#IfWinActive, ahk_class Winamp v1.x //이 녀석이 kmp플레이어 입니다.
#G::Send,{Down} // 활성창이 kmp플레이어면 각 버튼별로 할당된 값 실행
#H::Send,{Right} // 5초앞으로, 5초뒤로, 볼륨업, 볼륨다운
#J::Send,{Up}
#k::Send,{Left}
#IfWinActive, ahk_class GomPlayer1.x // 이 녀석은 곰플레이어
#G::Send,{Down} // 활성창이 곰플레이어면 각 버튼별로 할당된 값 실행
#H::Send,{Right} // kmp플레이어랑 마찬가지 입니다.
#J::Send,{Up}
#k::Send,{Left}
#IfWinActive // 이 녀석은 그외..
#G::Send,{WheelDown} // 즉 인터넷이나, kmp, 곰플등 설정된 값 이외에
#H::Send,{Browser_Forward} // 상황에서 적용되는 값입니다.
#J::Send,{WheelUp}
#k::Send,{Browser_Back}
===========================================================================================================
여기까지가 끝입니다.
왠지 어려워보이는데 한번 따라해보시길..
일단 UDF 실행해서 항목을 새로 만듭니다. 저는 autohotkey로 했습니다.
그리고 키값에 임의로 값을 넣는데 겹치면 안되니까 안쓰는 키로 넣어야합니다.
위에 소스에서 #이란건 윈도우키란 뜻입니다.
저같은 경우엔
윈도우키+J
윈도우키+K 윈도우키+H
윈도우키+G
이런식으로 할당했습니다. 윈도우에서 안쓰는키로 넣어야 작동합니다. 저랑 같이 하시는게 좋으실듯..
기존 UDF 설정 그대로 둔 상태에서 추가만 하세요.
위에 있는 내용중
#G::Send,{Down}
앞에 #이 윈도우키란뜻입니다.
윈도우키+G 면 다운이란 명령을 보내라 이런 뜻입니다.
# 윈키
! 알트
^ 컨트롤
+ 쉬프트
^G 면 컨트롤 + G 입니다.
여기까지 하셨으면 autohotkey를 설치합니다.
첨부해놓은 파일을 설치하면 아래 작업표시줄에 초록색 H 사각형 모양이 생겼을겁니다.
거기에 대고 마우스 우클릭하면 EDIT THIS SCRIPT 메뉴있는데 누르면 메모장이 뜹니다.
그 메모장안에 있는거 다 지우시고 첨부한 Ultra 텍스트파일 안에 있는 내용 복사하셔서
넣으신후 저장합니다. 그리고 다시 메뉴 누르면 있는 RELOAD THIS SCRIPT를 누르시면
위에 내용대로 실행됩니다. 그리고 시작메뉴에 autohotkey 넣으시면 다음부턴 그냥 되는거죠.
여기까지가 설치방법이고 사실은 제가 넣은 텍스트파일 내용도 본인에 맞게 먼저 수정해줘야합니다.
일단 kmp플레이어 경로 수정하셔야 하고
ahk_class IEFrame 요건 인터넷인데 아마도 다 똑같을것 같은데
곰플레이어나 kmp는 다를지도 모르니까 확인하셔야할듯..
다음은 원하는 실행프로그램 class 이름 확인하는 방법입니다.
autohotkey 메뉴를 누르시면 메뉴중에 WINDOW SPY 메뉴 누르시면 창이 뜹니다.
그 상태에서 원하시는 프로그램 실행시키고 WINDOW SPY 창 보시면 ahk_class xxxx 이런식으로
뜰겁니다. 그게 autohotkey에서 인식하는 프로그램 이름입니다.
그럼 그 이름 기억해놓으시고
#IfWinActive, ahk_class 클래스이름
#G::Send,{Down}
#H::Send,{Right}
#J::Send,{Up}
#k::Send,{Left}
이런식으로 수정하시거나 중간에 삽입시키면 됩니다.
삽입시키실땐 그외 실행하라고 한거 위쪽에 넣으셔야합니다.
휴.. 얼추 다 썼네요. 내용중 필요없는 부분은 지우시거나 바꾸세요. ㅎㅎ
명령에 활용할 키들은
http://www.autohotkey.com/docs/KeyList.htm
여기 보시면 그대로 쓸수있는 키들 이름 있습니다.
설명이 너무 어렵게 썼나 모르겠는데 더 자세히 하고 싶으시면 autohotkey 클럽 가입하셔서
공부 해보시기 바랍니다.
위에 내용에 대한 궁금증은 답글 달아주세요..
아는데까지는 설명드리겠습니다.
참고로 마메나 파이널번에서는 위에 내용 안먹힙니다.
그것때문에 하는건데.. ㅠ.ㅜ
하여간 할때마다 UDF버튼 눌러서 바꿀 필요없으니까 편합니다.
딜레이없이 잘 먹힙니다. ㅎㅎ
jar
1. 압축할때
jar cvf create.jar a.class b.class cDirectory
a.class,b.class,cDirectory를 create.jar라는 이름으로 생성합니다.
2. 압축풀때
jar xvf create.jar
create.jar의 내용을 추출합니다.
3. 압축된내용보기
jar tvf create.jar
create.jar의 내용을 봅니다.
사용법: jar {ctxu}[vfm0M] [jar-file] [manifest-file] [-C dir] files ...
옵션:
-c 새 아카이브를 만듭니다.
-t 아카이브에 대한 목차를 나열합니다.
-x 아카이브에서 명명된 (또는 모든) 파일을 추출합니다.
-u 기존의 아카이브를 업데이트합니다.
-v 표준 출력에 대한 자세한 정보 출력을 생성합니다.
-f 아카이브 파일 이름을 지정합니다.
-m 지정된 증명 파일에서 증명 정보를 포함시킵니다.
-0 저장만 수행하며 ZIP 압축을 사용하지 않습니다.
-M 입력 항목에 대한 증명 파일을 만들지 않습니다.
-i 지정된 jar 파일에 대한 색인 정보를 생성합니다.
-C 지정된 디렉토리로 변경하고 다음 파일을 포함시킵니다.
디렉토리인 파일이 하나라도 있으면 재귀적으로 처리됩니다.
'm' 및 'f' 플래그가 지정된 순서대로 증명 파일 이름과 아카이브 파일
이름을 지정해야 합니다.
예 1: classes.jar라는 아카이브 파일에 두 클래스 파일을 아카이브하려면 :
jar cvf classes.jar Foo.class Bar.class
예 2: 기존의 증명 파일 'mymanifest'를 사용하고 foo/ 디렉토리에 있는
모든 파일을 'classes.jar'로 아카이브합니다:
jar cvfm classes.jar mymanifest -C foo/ .
unix 에서 find 용법
- 파일 이름에 foobar 가 들어간 파일 찾기
find / -name "foobar" -print
- 특정 사용자(foobar) 소유의 파일을 찾기
find / -user foobar -print | more
- 최근 하루동안에 변경된 파일을 찾기
find / -ctime -1 -a -type f | xargs ls -l | more
- 오래된 파일(30일 이상 수정되지 않은 파일) 찾기
find / -mtime +30 -print | more
- 최근 30일안에 접근하지 않은 파일과 디렉터리를 별도의 파일로 만들기
find / ! ( -atime -30 -a ( -type d -o -type f ) ) | xargs ls -l > not_access.txt
- 하위 디렉터리로 내려가지 않고 현재 디렉터리에서만 검색하기
find . -prune ...
- 퍼미션이 777 인 파일 찾기
find / -perm 777 -print | xargs ls -l | more
- others 에게 쓰기(write) 권한이 있는 파일을 찾기
find / -perm -2 -print | xargs ls -l | more
- others 에게 쓰기(write) 권한이 있는 파일을 찾아 쓰기 권한을 없애기
find / -perm -2 -print | xargs chmod o-w
또는
find / -perm -2 -exec chmod o-w {} ; -print | xargs ls -l | more
- 사용자이름과 그룹이름이 없는 파일 찾기
find / ( -nouser -o -nogroup ) -print | more
- 빈 파일(크기가 0 인 파일) 찾기
find / -empty -print | more
또는
find / -size 0 -print | more
- 파일 크기가 100M 이상인 파일을 찾기
find / -size +102400k -print | xargs ls -hl
- 디렉터리만 찾기?
find . -type d ...
- root 권한으로 실행되는 파일 찾기
find / ( -user root -a -perm +4000 ) -print | xargs ls -l | more
- 다른 파일시스템은 검색하지 않기
find / -xdev ...
- 파일 이름에 공백이 들어간 파일 찾기
find / -name "* *" -print
- 숨겨진(hidden) 파일을 찾기
find / -name ".*" -print | more
- *.bak 파일을 찾아 지우기
find / -name "*.bak" -exec rm -rf {} \;
- *.bak 파일을 찾아 특정 디렉터리로 옮기기
mv `find . -name "*.bak"` /home/bak/
- 여러개의 파일에서 특정 문자열을 바꾸기
find / -name "*.txt" -exec perl -pi -e 's/찾을문자열/바꿀문자열/g' {} \;
find에 대한 참고문
find는 유닉스 및 리눅스 환경에서 중요한 유틸리티 중 하나이다. find는
파일의 이름부터 시작해서 수정 시간에 이르기까지 주어진 파라미터들과
일치하는 파일들을 찾아준다.
여기에서는 find에 대해 일부분만 다룬다. 조금더 알고싶은 유저는 한빛미디어
"유닉스 파워툴"을 참조하시기 바란다.
find의 기본문법
find path operators
path는 경로이다. 이 부분에 대해선 다음부분에서 약간 더 자세하게
설명할 것이다.
operators 는 연산자이다. 쉽게 풀이하자면 옵션인 셈이다. 여기에 들어갈
수 있는 것은 지금부터 소개할 것이다.
-name filename
우리가 가장 일반적으로 사용하는 옵션이다. filename에는 와일드 카드(별표)
가 들어갈 수 있지만 쉘이 변환하지 않도록 인용부호 쿼트(")로 둘러싼다
-perm mode
주어진 액세스 모드를 가진 파일을 찾는다. 액세스 모드는 8진수 값을 갖는다.
뒤에서 다시 설명한다
-type c
지정된 타입에 관해서 파일을 찾는다. c는 한글자로 된 코드이다. 예를 들면,
f는 일반 파일, b는 블록 특수 파일, l은 심볼릭파일을 나타낸다. 뒤에서 다시
설명한다.
-user name
이 옵션은 name에 해당하는 사용자 파일을 찾는다. name에는 사용자 id뿐만 아니라
사용자의 UID도 들어갈 수 있다.
-group name
이 옵션은 name에 해당하는 그룹의 파일을 찾는다. name에는 그룹명 뿐만 아니라
GID가 들어갈 수도 있다.
-size n
해당되는 사이즈의 파일을 찾는다. n은 블록길이의 파일을 찾는다. 한 블록은 512와 같다.
+n 이란 표시가 들어가면 n 블록보다 더 긴 파일을 찾는다라는 뜻이다. 파일이 클때
유용하다. nc라는 표현은 n 문자 길이의 파일들을 찾는다는 의미이다. ++nc는 무엇을
뜻할까? 뒤에서 다시 다룬다
-inum n
inode 번호가 n인 파일을 찾는다. 그다지 자주 사용되는 옵션은 아니여서 자세한
설명은 요약한다.
-atime n
n일 전에 액세스한 파일들을 찾는다. +n은 n일 이전에 액세스한(즉 n일 동안 액세스
하지 않은)파일들을 찾는다는 의미이다. 그러면 -n은 무엇을 의미할까? (즉, n일 동안
액세스한) 파일들을 찾는다" 의미이다. 뒤에서 다시 언급한다
-mtime n
파일의 내용이 수정된 시간을 검사한다는 것을 제외하고는 atime과 유사하다.
-ctime n
inode의 마지막으로 변경된 시간을 확인한다는 것을 제외하고는 atime과 유사하다.
"변경되다"라는 것은 파일이 수정되거나 그 특성 중의 하나가 변경되었다는 것(예를
들면, 그 소유자)을 의미한다.
-newer file
주어진 file보다 더 최근에 수정된 파일을 찾는다.
그런데 여기까기 find의 옵션을 살펴 보았는데 때때로 여러분은 조건을 만족하는
파일을 찾기 원할 것이다. 이럴때 쓰는 연산자가 있다. 다음이 그 연산자이다.
operator1 -a operator2
and 연산에 해당한다. -a는 생략이 가능하다. 두개의 검색 패턴이 같이 쓰여지면
find는 2개 모두와 일치하는 파일들을 원하는 것으로 가정한다.
operator1 -o operator2
or 연산에 해당한다. 둘 중 하나가 속하는 파일을 찾는다.
! operator
not 연산에 해당한다. operator에 해당하지 않는 파일들을 찾는다.
\(expression\)
논리 우선순위를 의미한다. 복잡한 표현식에서 위와 같이 지정해 주면 이 부분을
나머지 부분보다 빨리 계산한다. 여기서 (를 \( 로 표현했는데. 쉘이 해석할 수
있기 때문이다. php를 사용해 보신분이라면 무슨 얘기인지 대충 감 잡으셨을 것이다.
이번 부분은 find가 파일들을 찾았을때의 행위를 지정하는 그룹의 연산자들이다.
파일의 이름을 표준출력으로 출력한다. 뒤에서 조금 더 다룬다..
-exec command
찾은 파일들을 command로 처리한다. command에서 찾은 파일의 경로명을 포함
시키려면 중괄호를 사용한다 {} command는 명령을 실행시키고 난 뒤에는 반드시
백슬래시와 세미콜론을 사용한다. (\;)
-ok command
기본적으로 -exec 옵션과 같다. 그러나 해당 command를 실행하기 전에 명령을
실행할지에 대해 물어본다. 일반적으로 find를 테스트하는 데 많이 쓰인다고 한다.
위 옵션은 가장 일반적인 옵션들이지만 때때로 막강한 시스템 관리자들은 추가 또는
삭제하여 사용하기도 하니 여러분의 시스템에서 man find를 하게 되면 더 많은 옵션을
볼 수 있을 것이다.
1. 깊은 디렉토리 파고 들어가기
find의 가장 분명한 용도는 오래되고 큰 자료를 찾는 것이다. 또는 사용되지 않는
파일들의 위치를 찾아내는 능력이다. 그러나 근본적으로 가장 중요한 find의 특징은
서브 디렉토리로 내려가는 것이다.
보통 쉘은 인자 목록을 명령어에 제공해 준다. 그것은 UNIX 프로그램들에게 디렉토리명이
아닌 파일명들이 주어지는 이유이다. 단지 몇몇 프로그램들만이 디렉토리 이름을 받아서
서브디렉토리의 이름을 받아서 검색해서 내려갈 수 있다. find, tar, du, 그리고 diff 같은
프로그램이 그렇게 한다. chmod, chgrp, ls, rm 그리고 cp의 몇몇 버전들도 -r이나 -R
옵션이 주어질 때는 그럴 수 있다.
일반적으로는 대부분의 명령어들은 디렉토리 구조를 완전이 이해하지 못하며 쉘이 와일드
카드를 디렉토리 명으로 확장해 주는데 의존한다. 그러므로 어떤 디렉토리 그룹에서 .o로
끝나는 모든 파일들을 삭제하려면 다음과 같이 입력할 수 있다
find *.o */*.o */*/*.o
이렇게 하는 것은 입력하기 귀찮을 뿐 아니라 검색하는 모든 파일들을 찾을 수 없을지도
모른다. 쉘은 어떤 맹점이 있다. 점으로 시작하는 이름을 가진 디렉토리 내의 파일들은
찾을 수 없을 것이다. 그리고 */*/*/*.o 로 찾아지는 파일들이 있다면 삭제되지 않을 것이다.
또 다른 문제점은 위와 같이 입력하게 되면 Arguments too long이라는 에러 메시지를 내 뱉는다.
이것은 여러분이 입력한 와일드 카드를 쉘이 너무 많은 인자들로 확장했음을 의미한다.
find는 이런 문제점에 대한 해결책이다.
find의 가장 간단한 예는 다음이다
find . -print
find의 첫번째 인자는 디렉토리 또는 파일들의 경로이다. 위의 예제는 해당 디렉토리의
모든 파일들을 찾아준다. 경로명 뒤의 인자들은 항상 - 부호 (하이픈또는 대시라고 부른다)가
붙게 된다. 이것에 유의하기 바란다. 그리고 이 인자는 find가 무엇을 찾았을 때 어떤 행동을
취하는 가에 대해 명시한다. 그리고 다른 말로 이것은 검색 연산자들이다. 이경우엔 파일명이
출력된다. 특정 경로 이외에 C쉘에서는 틸드(~)도 사용할 수 있다. 예를 들어본다
find ~ ~barnett /usr/local -print
그리고 만약 따분하다면 다음과 같이 명령을 내릴 수도 있다
find / -print
위의 예제는 디스크에 있는 모든 파일들을 검색한다. 이 예제는 자신이 쓰는 워크스테이션에선
상관 없겠지만 여러 사람이 쓰는 웍 스테이션이나 서버에서는 범죄 행위일 정도로 디스크를
공회전 하게 낭비한다. 왠만해선 참아주기 바란다. 그러나 정말 필요하다고 생각될 시엔
/* 를 사용해 주기 바란다.
find는 결과를 표준 출력(stdin)으로 뿌리게 되니 발견한 파일의 목록을 다른 명령어로 보낼 수 있다.
이 기능을 사용한 한가지 방법은 치환이다. 다음 예제를 보자.
ls -ld 'find . -print'
find의 명령어의 실행 결과 출력이 역 인용부호 전체를 대신한다. ls는 find의 결과를 볼뿐 find
가 사용되었다는 것을 모른다. 또 다른 명령어는 xargs를 사용하는 방법이 있으나
여기에서 더 다루지 않겠다. 관심있는 유저는 한빛미디어 "유닉스 파워툴"을 보기 바란다.
2. -print 를 잊지 말자..
가끔 나는 find에 -print를 붙이는 것을 잊는다. 이것을 붙이지 않으면 검색결과가 출력되지 않는다.
(물론 GNU 버전에서는 그렇지 않으나 GNU 버전이 아닌 find에서는 꼭 붙여주어야 한다. 일부 버전에서는
-ls도 사용한다)
이것은 오래된 시스템 관리자도 가끔 잊고 초보 사용자들이 가장 잘 실수하는 내용 중 하나이니 조심하자
그리고 일부 버전은 -print를 추가해 주기도 하지만 기대해선 안된다.
3. 특정한 이름을 가진 파일 찾기
find 명령을 내릴때 메타 문자를 사용할 수 있는데 정규 표현식(grep과 같진 않다)를 사용할때 -name
연산자의 인자로 사용해서 그것들이 변경되지 않고 find로 넘겨지게 하려면 인용 부호로 감싸야 한다.
여기서 인용부호로는 어떤것을 사용해도 관계 없다.
find . -name \*.o -print
find . -name '*.o' -print
find . -name "[a-zA-Z]*.o" -print
파일 경로의 디렉토리들은 -name 연산자와 일치하지 않고 경로의 마지막에 있는 이름만이 일치한다.
예를 들어, 위의 명령어들은 ./subdir/afile이란 경로명과 일치하진 않지만 ./subdir/prog.o와는 일치한다.
경로의 중간에 있는 디렉토리과 일치하는 방법이 있다.
alias ff "find . -name '*\!{*}*' -ls"
파일이나 디렉토리의 이름을 넘겨주면 이 앨리어스는 그 인자를 포함하는 모든 파일이나 디렉토리
이름의 목록을 출력할 것이다.
4. 오래된 파일 찾기
7일된 파일을 찾고 싶으면 -mtime 연산자를 사용하면 된다
find . -mtime 7 -print
또 다른 방법은 시간의 범위를 지정하는 것이 있다.
find . -mtime +6 -mtime -8 -print
mtime은 파일의 최종 수정 시간이다. 사용되지 않은 파일을 찾아보려면 -atime 인자로 액세스 시간을 확인
하면 된다. 30일 이상 읽혀지지 않은 파일을 찾으려면 다음과 같이 하면 된다.
find . -type f -atime +30 -print
find 명령어가 디렉토리의 시간을 수정하기 실제로 액세스 되지 않은 디렉토리를 찾기란 어렵다. 각 파일과
관련된 연관된 또 하나의 시간이 있는데. ctime이라 불리는 inode 변경 시간이다. 그러나 여기에선 더 이상
자세하게 다루지 않는다.
5. find 검색의 최고봉이 되어보기
find는 확실히 까다롭다. 그러나 그 능력을 자유롭게 다루면 그 까다로움에 감사하게 될 것이다.(아직 필자는
그런 능력을 가지고 있지 않다)
find의 명령어들은 명령행의 복잡도와 상관없이 실제로는 위와 같은 것의 변형들일 뿐이다. 많은 다른 이름을
명시할 수 있고 오래된 파일들을 찾을 수 있다. 그 복잡함에 관계없이 실제로는 시작점이 어디이고 어떤
파라메터를 주고, 그리고 찾아낸 파일들을 어떻게 처리할 것인지 대해 명시하는 것 뿐이다.
더 복잡한 방법으로 find를 사용하는 것의 핵심은, 검색 파라미터는 실제로는 find가 평가하는 "논리 표현식(logical
expression)이라는 것을 깨닫는 것이다.(실제 find를 사용하는 대 부분의 유저는 논리 표현식을 사용하지 않는다)
즉. find는
한번에 하나씩 모든 파일들을 본다(솔직히 이것은 사실이다. 그러나 우리눈에 보일정도로 느리진 않다)
명령행 연산자가 제공한 표현식을 평가하기 위해 indoe에 들어있는 정보를 사용한다.(앞서 inode는 많이 사용하지
않는다는 얘기를 들어 생략했다)
표현식의 값이 참이면 지정된 행동을 한다.(예를 들면 파일의 이름을 출력하기 위해)
예를 들어 다음 표현식은 참이다
find / -name "*.c"
이런식으로 생각하게 되면 논리 연산자도 쉽다. 다음 표현식은 2개의 확장자에 해당되는 파일을 찾는다
-name "*.o" -o -name "*.tmp" -print
위 예제는 *.o와 *.tmp로 끝나는 파일들을 찾는다. 그럼 위의 확장자를 가진 파일을 찾는다면 다음의 표현식을
넣어 액세스 시간이 맞는지 검색한다
-atime +5 \( -name "*.o" -o -name "*.tmp" \)
find 안에 괄호를 넣으면 해당 부분을 먼저 계산한다. 앞에서 잠깐 설명했지만 괄호 앞에 \ 를 넣은건
서브 쉘 연산자로 의식하지 말라고 넣은 것이다.
그러나 위의 예제를 다음과 같이 바꾸면 참이 아니다.
atime +5 -name "*.o" -o -name "*.tmp"
위의 예제는 이름이 *.tmp로 끝난다. 이면 참이라는 틀린 식이 된다. 이 잘못된 표현식은 .tmp로 끝나는
모든 파일들에 대해 그 파일이 언제 액세스 되었간 간에 참이 될 것이다. 즉 -atime이 적용되지 않는다.
그러나 위의 표현식은 틀린 식이 아니다. 그러나 우리가 원하는 일을 하지 않을 뿐이다.
위의 예제를 조금 더 응용해서 현재 디렉토리에 있는 파일들을 찾으려면 다음과 같이 내리면 된다.
find . -atime +5 \( -name "*.o" -o -name "*.tmp" \) -print
그러나 반대로 위의 파일들만 찾지 않는다면 ! 연산자를 사용하면 된다..
find . ! -atime +5 \( -name "*.o" -o -name "*.tmp" \) -print
그러나 위의 표현식은 -atime 연산자에 대해서만 적용한다. 모든 연산자에 사용하려면 -atime 연산자에도
괄호를 아래와 같이 사용하면 된다.
find . ! \( -atime +5 \( -name "*.o" -o -name "*.tmp" \) \)-print
-print도 표현식이다. 이것은 항상 참으로 평가된다. 이외에 -ok, -exec 도 항상 참으로 평가된다.
이 표현식들이 좋게 사용될 때가 있긴 하다. 뒤에서 다시 다룬다.
그리고 여러분들이 find를 사용할 때 실수 하는 것 중 하나는 공백을 넣지 않는 것이다. 모든 연산자에는
공백이 필요함을 기억하기 바란다.
find가 찾는 시간들
일반적으로 -atime 부류의 연산자들에 대해서는 아쉽게도 문서화가 되어 있지 않다. 이 시간들은 일반적으로
일 단위이다.
부호없는 숫자. 예를 들어 3은 정확하게 3일 전에 끝난 24시간을 의미한다.(달리 말하면 96시간과 72시간 전 사이)
마이너스 부호를 가진 숫자는 그 시간 이후의 기간을 가리킨다. 예를 들어, -3은 지금과 3일 전 사이의 모든 시간이다.
(달리 말하면 0시간 전과 72시간 전 사이)
플러스 부호가 붙은 숫자는 그 시간 전의 24시간 기간을 가리킨다. 예를 들면 +3은 3일 이상 된 시간이다. (달리 말하면
96시간 이상)
정확한 파일 비교
"이 부분에 대해서는 언급을 생략한다. 위에서 언급한 책을 보면 자세하게 잘 나와있으니 참고하기 바란다."
찾은 파일 실행하기
find에서 찾은 파일을 실행할 수 있는데 여기서 -exec 연산자는 끝 부분에 항상 \;를 넣는다. 그러나 find가 다르게
취급하는 인자가 있는데 이 인자는 바로 중괄호이다. {} 이 두문자들은 find가 발견하는 파일의 이름을 갖는 변수이다.
예제를 보면 더 확실할 것이다. 다음 예제는 간단한 경우로써 -print 연산자를 흉내내는 echo 연산자가 있다.
find . -exec echo {} \;
c쉘은 {} 문자를 사용하지만 {}를 바꾸진 않으므로 이 문자를 인용부호로 덮어쌓일 필요는 없다. 그러나 \;에서 \는
''로 대체가 가능하다. 세미 콜론은 항상 ';'로 C쉘에서는 하는 걸로 익히자..
그리고 find안에 또 다른 find의 호출이 가능하다
여기에선 또 다른 호출에 대해서는 생략한다
-exec 커스터 테스트하기
-exec 연산자를 이용해서 커스템 테스트를 할 수 있는데 앞서 잠시 얘기했지만 되도록 -exec 연산자를 피하는게 좋다
사용해야 한다면 -ok 를 사용하는 방법과 확실히 그걸 실행해야 하는지 확인해 본다. 그리고 -exec 연산자는 꼭 find
명령의 뒤쪽에 놔두도록 한다.
HandTip
여기엔 기재하지 않았지만 \ 를 줄 바꿈 연산자로 사용할 수 있다. SQL에서도 사용가능하니 유용할 것이다. 다량의
명령어를 내릴때 상당히 유용한 기능이다.
find의 진정한 역할?
find의 진짜 역활은 파일의 위치를 찾는 것이 아니라 표현식을 평가하는 것이다. 그렇다. find는 확실히 파일의 위치를
찾아준다. 그러나 그것은 부수적인 것이다. 이점을 이해하는 것이 find를 이용하는 데에 있어 이해가 빠르고 find를
훨씬 더 자유롭게 유용하게 만드는 개념적인 발전이 될 수도 있다.
-type 연산자의 유형들
b - 블록 특수 파일("장치 파일")
c - 문자 특수 파일("장치 파일")
d - 디렉토리
f - 일반파일
l - 심볼릭 파일
p - 이름 파이프 파일
s - 소켓 파일
// 이 아래부분에서 더 이상 설명를 다루지 않습니다.
find . -size 1234c -print
- 보다 더 작은 , + 보다 더 큰
find . -name \*.o -perm 664 -print
find . -type d -perm 777 -print
----w---- 패턴은 -20과 같다.
퍼미션 8진 값
rwxrwxrwx 777
rwxrwxr-x 775
rw-rw-rw- 666
rw-rw-r-- 664
rw-rw---- 660
find . -perm -100 -print
실행가능한 --x------ 파일을 찾는다.
-perm 인자가 마이너스 부호를 가지게 되면 setuid 설정 비트를 포함한 모든 퍼미션 비트들이 검사된다.