Elasticsearch 를 인덱스, 데이터를 볼 수 있는 플로그인으로서 head보다 편하다..


https://github.com/appbaseio/dejavu




Posted by '김용환'
,


comm 커맨드를 실행하여 두 파일의 내용을 비교한다. 


$ cat > file.txt

1

2

$ cat > file2.txt


2


-1 매개 변수는 비교해서 첫번째 파일에만 있는 것은 출력하지 않는다. 

$ comm -1 file1.txt file2.txt


2


-2 매개 변수는 비교해서 두번째 파일에만 있는 것은 출력하지 않는다. 

$ comm -2 file1.txt file2.txt

1

2



-3 매개 변수는 비교해서 모두 존재하는 라인은 출력하지 않는다. 



$ comm -3 file1.txt file2.txt


1



comm 커맨드의 -3 매개 변수를 이용한 활용예시


$ comm -3 <(docker ps -a -q --filter=status=exited | sort)  <(docker ps -a -q --filter=exited=0 | sort) |  xargs --no-run-if-empty docker inspect 




Posted by '김용환'
,



트위터의 Future.rescure 함수가 마음에 들 때가 있다. (간결함이 좋다..)




https://twitter.github.io/util/docs/com/twitter/util/Future.html를 참조하면. 예외가 발생할 때 새로운 결과로 이어지게 한다. 코드가 간결해 진다. 


def rescue[B >: A](rescueException: PartialFunction[Throwable, Future[B]]): Future[B]

If this, the original future, results in an exceptional computation, rescueException may convert the failure into a new result.


import com.twitter.util.{Await, Future}
val f1: Future[Int] = Future.exception(new Exception("boom1!"))
val f2: Future[Int] = Future.exception(new Exception("boom2!"))
val newf: Future[Int] => Future[Int] = x => x.rescue {
	case e: Exception if e.getMessage == "boom1!" => Future.value(1)
}
Await.result(newf(f1)) // 1
Await.result(newf(f2)) // throws java.lang.Exception: boom2!




실제 예.


https://github.com/rodrigodealer/finagle_bootstrap/blob/master/src/main/scala/com/github/rodrigodealer/FacebookService.scala#L25

 def getToken : Future[Option[FacebookToken]] = {

    val request = GetRequest(s"/oauth/access_token?client_id=$apiKey&client_secret=$apiSecret&grant_type=client_credentials",

      "graph.facebook.com", true)

    perform(request) flatMap { token =>

      token.status match {

        case Ok => Future(Option(fromJson[FacebookToken](token.contentString)))

        case _ => Future(Option.empty)

      }

    } rescue { case _ => Future(Option.empty)}

  }



자바의 Future에는 rescue대신 exceptionally가 있다. 예쁘지 않다... 



AtomicBoolean thenAcceptCalled = new AtomicBoolean(false);

        AtomicBoolean exceptionallyCalled = new AtomicBoolean(false);

        CompletableFuture<String> future = new CompletableFuture<>();

        future.thenAccept(value -> {

            thenAcceptCalled.set(true);

        }).exceptionally(throwable -> {

            exceptionallyCalled.set(true);

            return null;

        });

        future.completeExceptionally(new RuntimeException());

        assertThat(thenAcceptCalled.get(), is(false));

        assertThat(exceptionallyCalled.get(), is(true));



Posted by '김용환'
,



elasticsearch에 terminate_after 라는 매개변수가 있다. 리눅스 커맨드로 따지면, 'head/tail -n 1 file.txt | wc -l '정도 될 것 같다. 


데이터가 있는지 먼저 확인한다.


// http://localhost:9200/_search?q=name:Andrew


{

  "took": 29,

  "timed_out": false,

  "_shards": {

    "total": 1,

    "successful": 1,

    "skipped": 0,

    "failed": 0

  },

  "hits": {

    "total": {

      "value": 1,

      "relation": "eq"

    },

    "max_score": 0.2876821,

    "hits": [

      {

        "_index": "company",

        "_type": "_doc",

        "_id": "AOmqCWwB3Ptn8KUa8r_2",

        "_score": 0.2876821,

        "_source": {

          "name": "Andrew",

          "age": 45,

          "experienceInYears": 10

        }

      }

    ]

  }

}




terminate_after는 size 매개변수와 함께 사용된다.



못찾으면 다음과 같은 결과가 나온다.

// http://localhost:9200/_search?q=name:kimchi&size=0&terminate_after=1


{

  "took": 841,

  "timed_out": false,

  "terminated_early": false,

  "_shards": {

    "total": 1,

    "successful": 1,

    "skipped": 0,

    "failed": 0

  },

  "hits": {

    "total": {

      "value": 0,

      "relation": "eq"

    },

    "max_score": null,

    "hits": [

      

    ]

  }

}

hits.total.value의 값은 0이다. 



찾으면 아래와 같은 결과가 나온다. 


// http://localhost:9200/_search?q=name:Andrew&size=0&terminate_after=1


{

  "took": 13,

  "timed_out": false,

  "terminated_early": false,

  "_shards": {

    "total": 1,

    "successful": 1,

    "skipped": 0,

    "failed": 0

  },

  "hits": {

    "total": {

      "value": 1,

      "relation": "eq"

    },

    "max_score": null,

    "hits": [

      

    ]

  }

}


hits.total.value의 값이 1이다. 



size=0의 의미는 검색 결과에 관심이 없음을 의미한다. terminate_after=1은 검색 결과에 맞는 결과가 1개가 나타나면 더 이상 검색하지 않고 종료된다.




Posted by '김용환'
,


도커의 모든 컨테이너를 삭제하는 커맨드이다. 


docker ps -a -q |  xargs docker rm -f




docker ps-a -q의 경과가 빈다면 파이프 다음 커맨드를 실행하고 싶지 않다면

--no-run-if-empty를 추가한다.




docker ps -a -q |  xargs --no-run-if-empty docker rm -f


Posted by '김용환'
,





두브르부니크는 아름답다.



성벽 투어를 하거나 old ciy를 하다 보면 산 하나에 올라가고 싶은 마음이 드는데

스르즈 산이다.




보통 old city 위에 위치한 케이블 카 센터에서 왕복 티켓을 사서 케이블 카를 타고 다닌다. 길어야 5분 정도 걸린다.




개인적으로 이런 산은 높지 않아서 자신이 있었지만... 

특히 두부르부니크를 지켜낸 크로아티아인의 마음을 느끼고 싶었다.


스르지 산에 올라가로 결정한다.


여름이라 굉장히 덮다.

걸어 올라갈 때는 시원한 음료수를 챙겨 가길 바란다. 목이 많이 마르다.

늦은 오후, 밤에는 절대 등산, 하산 하지 않길 바란다.
(길을 밝히는 등이 없다. 

참고로 등이 있는 부다페스트 시타델라도 엄청 무섭다...
스르지산은 아무 등도 없으니 늦은 오후에는 도전하지 않길 바란다)



스르지 산을 올라가는 길은 하나인데, 잘못 갈 수 있다.




올라가는 방법은 아래 지도를 참고 한다. 그냥 old city에서 올라가면 길이 없을 수 있다.




무척 대고 올라간지라 나는 이상한 곳으로 올라갔다.





잘못 간길이라... 포기할까 했는데..

가다 보니, 내가 온 길로 외국인 일행이 걸어와서. 물어보니 방향을 알려주었다.

(위험하다고 생각되면 바로 되돌아가 가길 바란다. 위에 소개한 안전한 길로 가길 바란다. 

걷는 것이 힘들 수 있으니 케이블 카도 좋은 방법이다.) 


걷는 사람이 거의 없긴 하지만, 도움 받으면서 산 입구에 도착했다.





산행 길을 시작한다. 





점점 아름다운 두부르부니크가 나온다. 

정말 아름답다.. 정말 아름답다.

고향 두브르부니크를 보호한 크로아티아인의 마음이 느껴진다.




걸어서 올라가니, 아름답니다. 

더운 여름날.. 정말 뜨거운 여름 날이지만 행복하다.


순례길 같다. 



스르스산에 드디어 올라갔다. 아름답다. 




스르지 산 반대편은 보스니아-헤르체코비나 땅이다. 구글 지도를 보며 자세히 길을 보면 철책도 보인다. 






Posted by '김용환'
,



bash에 for each 문을 curl과 결합할 수 있다. 


for i in {1..10}; do

  curl -X GET "http://localhost/api/v1/orders/$1" -H "accept: application/json;charset=UTF-8"

done



수 천개의 파일에 매개 변수를 넣어 확인하려면 {1..10} 대신 $(cat file)으로 변경만 하면 된다.


for i in $(cat file); do

  curl -X GET "http://localhost/api/v1/orders/$i" -H "accept: application/json;charset=UTF-8" 

  sleep 1

done



비슷한 사례로서, host 장비의 ip를 얻고 싶다면 다음 코드를 사용한다. 



for i in $(cat hosts); do

   ping -c1 $i | grep bytes | grep PING | awk {'print $2 substr($3, 1, length($3)-1)'}
   sleep 1

done





Posted by '김용환'
,


엄청 많은 암호화된 단어를 저장한 수 백개의 단어를 한번에 java 코드에서 복호화하고 싶다. 


awk로 특정 데이터를 뽑아냈다.


MDBlOTVkMTZhMzNiNjRjZjI2MTg2ZGFiOTBiMjdmMWY

...

ZTM1ZDAyYTA2NjhhMzVlZjhmZmJhZTA0M2JlZmQ2NDg

MWRjODkzM2Q5MWI1NzdiNjRkOTVmOWU4OTNjYjgyMDc



이럴 때는 아래와 같은 sed 커맨드를 사용한다. replace(s)를 사용해 앞과 뒤에 쌍따옴표(")를 붙이고 중간에 기존 단어를 사용하게 한다. 



$ sed 's/^/\"/; s/$/\"/' file

"MDBlOTVkMTZhMzNiNjRjZjI2MTg2ZGFiOTBiMjdmMWY"

...

"ZTM1ZDAyYTA2NjhhMzVlZjhmZmJhZTA0M2JlZmQ2NDg"

"MWRjODkzM2Q5MWI1NzdiNjRkOTVmOWU4OTNjYjgyMDc"



배열로 복호화하기 때문에 , 를 맨 앞에 넣는다.


$ sed 's/^/,\"/; s/$/\"/' bb


, "MDBlOTVkMTZhMzNiNjRjZjI2MTg2ZGFiOTBiMjdmMWY"

...

,"ZTM1ZDAyYTA2NjhhMzVlZjhmZmJhZTA0M2JlZmQ2NDg"

,"MWRjODkzM2Q5MWI1NzdiNjRkOTVmOWU4OTNjYjgyMDc"



맨 앞의 , 만 빼면 되니 배열로 쉽게 코딩할 수 있다. 



String[] encrypteds = new String[] { "MDBlOTVkMTZhMzNiNjRjZjI2MTg2ZGFiOTBiMjdmMWY"

.. ,"ZTM1ZDAyYTA2NjhhMzVlZjhmZmJhZTA0M2JlZmQ2NDg"
,"MWRjODkzM2Q5MWI1NzdiNjRkOTVmOWU4OTNjYjgyMDc"

Arrays.stream(encrypteds) .map(enc -> decryptAES(enc)) .forEach(System.out::println);

};


Posted by '김용환'
,

두브르부니크 old city 에서 집시에게서 지갑과 돈을 모두 잃어버렸다. 

다행히 여권은 찾았고 두브르부니크 여행시 알면 좋을 내용이 있다.



두브르부니크에는 크로아티아 경찰 외에 외국 경찰들이 있다. 워낙 많은 사건/사고들이 많은 지라 여러 국가 경찰(제가 들은 분들은 미국, 영국, 프랑스, 이탈리아 )들이 있는데. 특히 한국 경찰, 2분이 3주마다 돌아가서 지켜주고 있다.


처음에 현지인의 도움을 받아 경찰서에 가서 크로아티아 경찰, 한국 경찰 분들의 도움을 받아 신고했지만, 아직까지 범인들을 찾지 못했지만 여권은 찾아서 다행이었다.


하나 비바 카드 덕택에 잘 돌아왔습니다. 씨티 카드 만큼 훌륭한 카드였다. 조금 돈을 넣어두었는데. 유용하게 사용했다. ATM이 있는 곳이라면 돈을 뺄 수 있다. 정말 old city에는 ATM 기기가 많다.



두브르브니크에서 여권을 잃어버려면 지리적인 부분(중간에 보스니아 땅이 있음) 비행기와 도로로 수도 자그레브까지 이동을 못한다. 따라서 배를 타고 이동해 수도 자그레브로 이동해야 하는데, 크로아티아 경찰들도 자기 스케쥴이 있어서 잘 만나기 쉽지 않고, 여권 분실시 대사관가서 작업해야 해서 최소 1주일이 걸릴 수도 있다고 한다.





(크로아티아 수도인 자그레브까지는 엄청 먼 곳이다.)






동양인 커플등을 주로 타겟으로 잡아서 골치라고 하니 참고 하길 바란다.

그래서 두브르부니크에서는 가방을 맬때는 중국처럼 꼭 앞으로 매길 바란다. 집시가 집시처럼 옷을 입지 않는다. 관광객처럼 돌아다닌다. 

짐이 거의 없고 옷도 너무 편하게(가볍게) 입고 거의 탄 얼굴이면 조심할 필요가 있다. 집시일 가능성이 높다. 



여권을 반드시 제일 중요하게 여겨야 한다.
현금 도난에 대한 보험은 한국에 아예 없다. (여행 보험사인 삼성생명에서 확인)
현금도난에 대비해 씨티 카드나 하나 비바 카드를 꼭 만들자. (비상금)


혹시 두브르부니크 경찰서에서 가야한다면 한국인 경찰관을 불러주시면 도와주실 것이다.




두브르부니크 경찰서 위치는 다음과 같다.



old city에서 상당히 멀리 떨어져 있다..

10번 버스가 경찰 근처까지 가니 참고바란다. (GPS보고 내려야 함)


Posted by '김용환'
,


도커의 network 설정 중 bridge는 docker0이라는 네트워크를 사용한다. 



$ docker network inspect bridge

[

    {

        "Name": "bridge",

        "Id": "2b3831fb8f909d0a44d7a74f4f0df3327f1f02409096b4b8f4ba5a2ce5a5a7d6",

        "Created": "2019-06-28T22:52:24.973773315Z",

        "Scope": "local",

        "Driver": "bridge",

        "EnableIPv6": false,

        "IPAM": {

            "Driver": "default",

            "Options": null,

            "Config": [

                {

                    "Subnet": "1.1.0.0/16",

                    "Gateway": "1.1.0.1"

                }

            ]

        },

        "Internal": false,

        "Attachable": false,

        "Ingress": false,

        "ConfigFrom": {

            "Network": ""

        },

        "ConfigOnly": false,

        "Containers": {},

        "Options": {

            "com.docker.network.bridge.default_bridge": "true",

            "com.docker.network.bridge.enable_icc": "true",

            "com.docker.network.bridge.enable_ip_masquerade": "true",

            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",

            "com.docker.network.bridge.name": "docker0",

            "com.docker.network.driver.mtu": "1500"

        },

        "Labels": {}

    }

]




host라는 모드가 있는데 이는 eth0을 사용하는 것이다. 

$ docker network inspect host

[

    {

        "Name": "host",

        "Id": "ee9bddcf9dc5a7804f63522a9740d3226e8df3ce31575cfc9a7ebbd0f7d5a23d",

        "Created": "2018-10-15T07:14:31.9624055Z",

        "Scope": "local",

        "Driver": "host",

        "EnableIPv6": false,

        "IPAM": {

            "Driver": "default",

            "Options": null,

            "Config": []

        },

        "Internal": false,

        "Attachable": false,

        "Ingress": false,

        "ConfigFrom": {

            "Network": ""

        },

        "ConfigOnly": false,

        "Containers": {},

        "Options": {},

        "Labels": {}

    }

]


또한 17.06부터 docker container create를 사용할 때 --network host를 사용하면 eth0을 바로 사용할 수 있다. 



kubernetes에서도 이와 비슷한 기능이 있다. 

pod의 모든 컨테이너에서 노드의 eth0을 사용할 수 있도록 HostNetwork(즉 hostNetwork: true)을 설정할 수 있다.  








Posted by '김용환'
,