tar 사용시 주의사항

gzip은 여러개의 파일을 묶는 기능이 없다. 

따라서 여러개의 파일을 묶어서 압축하려면 tar와 같이 사용하던가 zip같은 다른 압축포멧을 사용해야 한다. 

꺼꾸로 tar는 묶는 기능만 있고 압축하는 기능이 없다.  물론 z 옵션을 주어 다 묶은후 gzip으로 압축하게 하는 기능은 있다. 


그럼 왜 이렇게 불편한 tar를 쓸까? 


tar는 해당 파일의 심볼릭 링크나,  user id, group, permission등 파일 메타정보도 모두 저장하고 복구하게 되어있다.  

그래서 유닉스 시스템의 파일들을 정상적으로  복구시키기 위해서 tar를 사용하게 된다. 


그런데 리눅스에서 FAT32에 tar 파일을 풀때 문제가 발생한다. 



문제는 FAT32 파티션을 마운트하면 해당 파티션은 마운트 한 유저의 권한, 소유로 마운트되게 된다. (user id, group id등) 일반적으로 root이다. 


여기에 tar 파일을 풀려고 한다면 tar는 해당 파일에서 파일을 추출해 내고,

추출해 낸 파일을 tar에 기록된 원래 압축한 사용자의 user id, group으로 변경시키려고 시도한다. 


그러나 FAT32 파일시스템은 소유에대한 정보를 저장하지 않는 파일 시스템이며 이에대한 변경시도는 실패하며 결국 root:root로 남아 있게 된다. 


tar는 user id , group id 변경 시도가 실패했으므로 압축해제를 중단시키게 된다. 


따라서 tar로 FAT32에 압축을 풀기 위해서는 원본이 root:root이 되어 있거나 

풀기옵션에 소유권을 복구하지 않게하는 옵션을 주어야 한다.

by 밀리네스 | 2009/06/18 17:38 | 트랙백

Linux에서 파티션 숨기기.

linux에서 USB로 부팅한 루트 디스크나 복구용 이미지등이 포함되어 있는 파티션을 숨기고자 할때가 있다. 

그럴때는 HAL을 통해 해당 파티션을 무시하게끔 설정해주면 된다. 

1. UUID
vol_id --uuid  [대상 파티션 디바이스명]
ex) vol_id --uuid /dev/sda1
4A38-46C5

으로 해당 파티션의 UUID를 얻어온다. 


2. UDI
이렇게 얻어온 UUID는  구분자 -(Dash)인데 이 -를 _(Underbar)로 바꾼후
lshal | grep [Converted UUID] 를 실행하여 대당 기기의 HAL UDI를 얻어온다. 


ex) lshal | grep 4A38_46C5
udi = '/org/freedesktop/Hal/devices/volume_uuid_4A38_46C5'
  info.udi = '/org/freedesktop/Hal/devices/volume_uuid_4A38_46C5'  (string)


3. Set HAL property
이렇게 얻어온 UDI를 가지고 프로퍼티를 바꿔어 주면 된다 

sudo hal-set-property --udi /org/freedesktop/Hal/devices/volume_uuid_4A38_46C5 --key volume.ignore --bool true

이렇게 HAL에서 해당 기기의 volume.ignore 프로터피를 true로 지정해주면 Gnome desktop등에서 이 파티션을 무시하고 보여주지 않게 된다. 

sudo /etc/initd.d/gdm restart 등으로 데스크탑을 다시 띄워보면 적용됨을 확인할수 있다. 


4. HAL Policy
물론 이것은 재부팅되면 사라지는 1회성 이다. 이것을 매번 부팅때마다 적용시키고 싶다면
/usr/share/hal/fdi/policy/ 
/etc/hal/fdi/policy
에 HAL 정책파일을 추가해주면 매번 부팅될때마다 적용되게 된다. 


<?xml version="1.0" encoding="UTF-8"?>
<deviceinfo version="0.2">
<device>
    <match key="volume.uuid" string="E6C5-A7A9">
      <merge key="volume.ignore" type="bool">true</merge>
    </match>
    <match key="volume.uuid" string="21fd63b4-3d68-4518-a61b-1021a3caa237">
      <merge key="volume.ignore" type="bool">true</merge>
    </match>
  </device>
</deviceinfo>


참고 : 
http://people.freedesktop.org/~david/hal-spec/hal-spec.html
http://june3474.blogspot.com/2007/08/6-udev-hal-gnome-volume-properties.html
http://salgunamu.tistory.com/438

by 밀리네스 | 2009/06/18 17:26 | 트랙백

요즘 NBA은 수비를 않하는군요 -_-

몇년만에 NBA를 볼려고 이번 파이널 경기들을 보고 있는데..



왜이리들 기본기가 떨어지는 겁니까..
파이널에서 이런 수비라니..

자리잡는법도 모르는거 같고
가드가 일부러 어려운 자리가서 패스하고..

공이 떨어졌는데 멍하니 보고있고, 
공가진 사람이 페인트존에 들어왔는데 쳐다보고 있고..


진짜 수준 많이 떨어졌네요..

by 밀리네스 | 2009/06/11 09:38 | 트랙백 | 덧글(4)

정치력이 중요하다.

멍청한, '빨대 꼽힌' 대학생의 소심한 반론

세상을 바꾸는 것은 정치다. 


정치는 별개 아니다, 서로 이해관계가 충돌하는 이슈에 대해 대응해나가것 자체가 정치이다.

그러니 “정치적으로 해석하지 마세요”라던가 하는 부류의 말들이 얼마나 자신의 권리를 포기하는것인가는 좀 생각들좀 해보기 바란다. 


정치가 이슈에 대한 대응이라면 정치력은 무었일까?

간단히 말하면 이슈에 대해 내가 원하는 방향으로의 결과를 도출해내는 힘을 말한다. 


정치력의 발휘에서 “멍청한 애송이”와 “쩔어빠진 늙은이”가 차이가 나는 것이다. 


젊은이는 이상을 말한다. 아는게 그것밖에 없거든. 젊은이는 자신의 의견이 아닌, 배운 의견을 말하게 되어 있다. 

특히 우리나라에서는 “자신의 의견을 생각하고(심화시키고) 표현”하는 것을 교육이 가르쳐 주지 않기 때문에  이 문제가 특히 심하다. 

그렇기 때문에 젊은이들은 “자신의 이상에서 어긋나면 그것은 틀린것“이라고 생각하는 습성이 있다. 


그래서 자신의 취향(이상이라고 말하고 싶지만 그게 진짜 이상일리가 없으니)에 딱 맞는 정당이, 정치인이 없다고 정치에서 눈을 돌린다. 


다음을 보고 오자( 저작권이 있는 그림이라 링크만 건다)

http://kr.engadget.com/2009/05/25/gadget-man/ 


세상에 자신의 취향에 딱 맞는 정치인, 정당, 정치사상은 존재하지 않는다. 




잘 생각해보자. 


자기 자신조차 자신의 취향에 맞지 않는데 

자신의 취향에 맞는 정당, 정치인, 정치사상 그런게 있을거 같은가?


진실로 대학생을 대변하는 정치조직?  이게 얼마나 허황된 것인지를 모른다면 참 할말이 없다. 



그런데 그럼에도 불구하고 ”쩔어빠진 늙은이“들은 자신에 취향에 딱 맞지는 않은 정당을 지지하여 ”큰 규모의 정치력을 형성”한다. 

그리고나서 그 형성된 정치력을 자신의 이해관계에 이용한다. 


결국 정치에서는 정치력이 큰쪽이 더 큰 파이를 얻어가게 되어 있다. 



그런데 단지 취향에 맞지 않는다는 이유로  정치를 포기하면서 

그래서 아주 작디 작은 정치력만을 발휘하면서 심지어는 투표조차 하지 않으면서(그걸 또 자랑으로 생각하면서)


“왜 나에게 돌아오는 파이는 이렇게 작은가”라고 외치는것은 참으로 공허하다. 



by 밀리네스 | 2009/06/02 12:37 | 트랙백

내가 믿는 지식 한가지


인간의 두뇌는 23~5세를 기준으로 자아와 인격이 확립되며,  이 이후로는 병이나 사고등으로 두뇌에 변화가 일어 나기 전에는 자아 와 인격에 큰 변화는 일어나지 않는다. 

라는 지식이 있습니다. 

이 지식에 따르면 "세대는 변할수 있지만 사람은 변하지 않는다"라는 결론이 나옵니다. 
(다른 사람을 변화시키려는 대부분의 노력은 실패하며 유일하게 성공 가능성이 높은 것은 다음 세대를 가르치는 것이라는 의미지요)

그런고로 저는 다른 사람과 논쟁을 하여 결론을 낼수는 있다고 생각하지만 그 결론에 따라 사람이 변할것이라고 생각은 하지 않습니다. 
그리고 그 사람이 변하는 것을 전제로하는 논쟁은 애시당초 실패할것이라고 생각하지요. 

감정의 흔들림에 의해 잠시 자신의 자아에 어긋나는 행동을 하는 경우는 있겠지만, 최대 3개월이 지나면 다시 자신의 자아에 따르게 되어 있는것이지요. 
(그러므로 사람/자신을 바꾸고 싶다면 "습관"을 바꾸는 것에 집중해야 한다는 의미도 됩니다)

아무튼, 저는 사람들이 깨달았다, 변했다 이런거 않믿습니다. 

사람들이 변했다/정신차렸다고 믿고 계신분들은 나중에 상처받지 않으시길 바랍니다. 

by 밀리네스 | 2009/05/27 13:07 | 트랙백 | 덧글(1)

그런 사람이라고 생각했는데 진짜 그런 사람이였네..

흔히 말하는 목숨 걸고 도전한다라는 거..
진짜로 해버리는 사람일꺼라고 생각은 했지만 진짜로 해버렸다. 

아...

잘가시길..

by 밀리네스 | 2009/05/23 12:19 | 생각 | 트랙백

SSH by history

작업해야 하는 기기가 많을때 일일히 id, ip, password를 치는것은 매우 고된 일이다. 
그래서 히스토리에 기반해서 ssh 접속을 돕는 스크립트를 만들어 보았다. 


#!/bin/bash

password=$2
addr=$1

echo $addr
host=${addr#*@}
id=${addr%%@*}



if [[ "$host" =~ ^[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+$ ]]
then
lastword=${host##*.}
echo "$lastword $id $host $password" >>  ~/.ssh/alias
sort ~/.ssh/alias | uniq > ~/.ssh/alias.tmp
rm ~/.ssh/alias
mv ~/.ssh/alias.tmp ~/.ssh/alias
target="$id"@"$host"
shift
shift
sshpass -p $password ssh -oStrictHostKeyChecking=no $target $*
exit 0
fi

if [[ "$addr" =~ ^[^.]+$ ]]
then
line=`cat  ~/.ssh/alias | grep ^$addr`
echo $line
id=`echo $line | awk '{print $2}'`
host=`echo $line | awk '{print $3}'`
password=`echo $line | awk '{print $4}'`
target="$id"@"$host"
shift
sshpass -p $password ssh -oStrictHostKeyChecking=no $target $*
exit 0
fi


이파일을 ~/bin 등 path가 잡힌 디렉토리(순서상  /usr/bin 보다 먼저 나와있는 )에 ssh라고 만들어 둘것

최초접속시 
ssh id@ip password

이후 접속시 IP의 마지막 번호
ssh LASTNO

ex)
ssh root@192.168.0.100 1234567890
이후
ssh 100


나는 ip 기반으로 500여대의 서버를 관리해야 하는지라 ip만 사용하기때문에 ip만 자동으로 히스토리로 기록한다. 
~/.ssh/alias 파일에 손으로 직접 입력해도 된다. 
alias파일을 직접 수정하면 굳이 IP의 마지막 번호일 필요가 없다. 

ServerA root 192.168.0.199 12341234
이렇게 추가해두면
ssh ServerA 로 접속할수 있다. 


ps.  sshpass는 ssh의 interactive password  를 통과시키는 툴이므로 미리 설치해두어야 한다. 
ps2. 당연히 편하고자 만들것이니 보안문제(패스워드를 alias 파일이 기록해두는것)는 무시하고 만든것이다. 주의해서 사용할것. 

by 밀리네스 | 2009/05/13 19:18 | 트랙백

no row with the given identifier exists

Hibernate를 사용하다 보면 

no row with the given identifier exists

라는 예외를 만날때가 있다. 

다양한 원인이 있겠지만,  내가 만난 경우는 이렇다. 

A ----*  B 

A가 있고 B가 A에 속한다. 그리고 하나의 A에 대해 B가 다수 존재할수 있다. 

이럴때 Hibernate 설정은 다음처럼 된다. 

<class name="B">
  <many-to-one class='A" name="parent" column="A_ID"/>
</class>


평상시에는 잘 돌아간다.  문제는 외부키 A_ID로 지정된 A의 레코드가 어떤 원인으로 지워졌을때이다. 

getHibernateTemplate().get(B.class, 100L);


를 호출 하면 no row with the given identifier exists 예외가 발생한다.

B레코드는 존재하지만 B와 연관된 A레코드가 존재하지 않기 때문에 발생하는 것인데..(관리자가 실수로 지운듯)


이것에 대한 일반적인 해결책은 잘 모르겠다.


Hibernate 사이트에서는 무결성 제약조건을 제대로 지켜라..라고 하지만 사실 현업에서 외부키 제약사항 제대로 걸어놓은 사이트가 얼마나 되는가...


게다가 저 DB는 B는 내용이 변하고 A는 새로운 레코드가 만들어지는 그런 특성을 가지고 있으며 B가 한달정도의 시간이 지나면 다른 A로 옮겨가야 한다.

그래서 A를 주기적으로 지우기도 한다.


아무튼 이부분 때문에 고생좀 했다. HQL을 이용해서 A와 연관만 제외한 데이터만 얻어와서 객체를 만들어 쓰게 했는데.. 

Hibernate같은 솔루션들이 일반적으로 가지는 "우리방식 아니면 지원 않해요"라는 문제인지라 어쩔수가 없는듯 싶다.


ps. Hibernate에서 이런 문제를 해결하는 솔루션을 아시는분은 좀 알려주세요. 

by 밀리네스 | 2009/04/20 17:01 | 트랙백

새벽. 고양이들의 집회.

새벽에 고양이들이 울음소리때문에  잠에서 깨어났다. 
나가보이 집앞 대문앞에 약 20마리쯤 되는 고양이들이 모여서 울어대고 있었다. 
아주 발악을 하는 녀석도 있어서 엄청 시끄러웠다. 

발정기라서 그런건지, 집회를 하는건지는 모르겠다
 
"내일 결행, 내일결행"하면서 합체고양이몬스터를 만들어낼 생각을 하는것일지도 모르겠지만.

아무튼 너무 시끄러워서 나말고도 여러집에서 사람들이 하나둘 나오기 시작하더라. 

그래서 대충 문열고 나가니까 알아서 해산하더라.

혹시 내일도 집회 할지도 모르겠다. 그땐 사진좀 찍어봐야지. 

by 밀리네스 | 2009/04/20 12:40 | 일상 | 트랙백

Hibernate와 Mysql Date 버그

Java에서의 Date 값과 DBMS에서 지원하는 Date 값이 일치 하지 않을 수도 있다는건 매우중요한 사실이다. 
입력했다가 받아오면 시분초가 짤리는 DBMS도 있다. 


짤리기뿐만아니라 검색이 제대로 않되는 문제도 있다. Mysql의 경우 버전에 따라 날자 검색이 제대로 않되서Date date = new Date(2009-1900, 3-1, 1);을 DB에 입력한후 
criteria.add(Expressions.eq("targetDate", new Date(2009-1900, 3-1, 1))) 
로 검색하면 검색이 되질 않는다. 
저 날자를 검색하려면

Date d = new Date(2009-1900, 3-1, 1);
Date start = new Date(d.getTime()-1);
Date end = new Date(d.getTime()+1);
criteria.add(Expressions.ge("targetDate", start)). add(Expressions.le("targetDate", end));

이런식으로 검색하여야 한다.

혹시 이문제를 해결할수 있는 다른 방법 아시는분은 좀 알려주세요.



by 밀리네스 | 2009/04/18 01:52 | 트랙백

◀ 이전 페이지다음 페이지 ▶