読者です 読者をやめる 読者になる 読者になる

/dev/null

(◞‸◟)

Eclipseでcom.sun.net.httpserver.HttpServerが解決できないとき

MaxOSX 10.9.5

Eclipse4.3SR2

Java1.7 ~ 1.8

プロジェクトのSDKを1.7→1.8→1.7と変更テストをしてたら、

com.sun.net.httpserver.HttpServer が解決されなくなった。 それまでは問題なく使用出来ていた。

調べてると同様の事例が見つかった。

stackoverflow.com

jarをそのままDLしてもってきてプロジェクトに入れる、みたいのが示されてるけどいままで問題ないのでそれはなし。

こっちが重要で

java - Eclipse cant recognize com.sun.net.httpserver.HttpServer package - Stack Overflow

プロジェクト設定→BuildPath→Librariesを選んで。その中のJRE System Libraryを展開し、 Access rules をEditする。

Accessible に com/sun/net/httpserver/**: という文字列を入れて再度プロジェクトをbuildし直すと問題なく解決出来た。

f:id:gitpub:20150420181654p:plain

com.sunパッケージのクラスはこんなことになることがあるっぽい。

java - Access restriction: Is not accessible due to restriction on required library ..\jre\lib\rt.jar - Stack Overflow

CentOSでGNU Parallelを入れたけどなんか動かねえなってとき。

yumからGNU parallelを入れた。

yum install -y parallel

で、サンプル的に試す。

[root@server ~]#  parallel echo ::: hello world !
parallel: Warning: YOU ARE USING --tollef. IF THINGS ARE ACTING WEIRD USE --gnu.
parallel: Warning: --tollef is obsolete and will be retired 20140222.
parallel: Warning: See: http://lists.gnu.org/archive/html/parallel/2013-02/msg00018.html

/bin/bash: :::: command not found
/bin/bash: hello: command not found
/bin/bash: world: command not found
/bin/bash: -c: line 0: syntax error near unexpected token `newline'
/bin/bash: -c: line 0: `!'

yumで入るparalellはtollefモードとやららしく、GNUのやつじゃない。

--gnuオプションいれると良い

[root@server ~]#  parallel --gnu echo ::: hello world !
hello
world
!

知るかよそんなもんって感じだ。

都度--gnu入れるの忘れるのでデフォルトを--gnuで動かすようにするには

/etc/parallel/config を開いて --tollef になってるところを --gnu にして終わり。

[root@server ]#  parallel echo ::: hello world !
hello
world
!

【Go】structにデフォルトの値を設定したい

Golangでstructを生成するときにこのフィールドは特定の値で初期化してほしい、みたいな場合があります。

例えば検索に使うパラメーターオブジェクトのような。

package main

import "fmt"

// sturct
type UrlParam struct {
    Keyword string
    Format string
}


func main() {
    param := UrlParam{}
    param.Keyword = "golang"
    param.Format = "json"
    fmt.Println(param)
}

Keywordは都度設定したいですが、formatに関してはデフォルトがjsonになっていてほしい。 変えたければxmlとか指定したい。

intなどは0で初期化されますが、stringの場合は空文字列です。

こういう場合は普通にコンストラクタっぽいものを作れば良い。

func NewParam (keyword string) * UrlParam {
    u := new(UrlParam)
    u.Format = "json"
    u.Keyword = keyword
    return u
}

構造体のフィールドの数が少なければこういう方が簡潔

func NewParam2 (keyword string) *UrlParam {
    return &UrlParam{keyword, "json"}
}

ポインタじゃないのが欲しければこう

func makeParam(keyword string) UrlParam {
    return UrlParam{keyword, "json"}
}

当たり前のことは当たり前に書けば良さそう。

コマンドの実行結果にcdしたいとき

たまにあります。

which hoge で 取得したパスにcdする、的な。(出来たとしても hoge is not directoryとなるが)

例えば 今日の日付でディレクトリを作ってそのディレクトリにサクッと入りたいときとか

date +'%Y%m%d' |xargs mkdir ←20141209みたいなディレクトリが出来る

date +'%Y%m%d' |cdbashだと何も起こらず、zshだと(pwd now: ~)

なのでxargsで渡してみる

[vagrant@dev ~]$ date +'%Y%m%d' |xargs mkdir
[vagrant@dev ~]$ date +'%Y%m%d' | xargs cd
xargs: cd: No such file or directory

うまくいきません。 xargsは実行可能ファイルにのみ引数を受け渡すことが出来ますが、cdはbuilt-inのコマンドのため使えません。

`` でコマンドの実行結果を包んでcdするとうまいこと実行できます。 詳しくはサブプロセスが云々とかでよくわかってない。

[vagrant@dev ~]$ cd `date +'%Y%m%d'`
[vagrant@dev 20141209]$

fabricでリモートホストのログファイルをtailするスクリプトを書くTips

fabricでリモートホストのログファイルをtailするスクリプトを書くという事があります。

多分安直に書くとこんな感じ

from fabric.api import sudo,env

env.hosts=['ap1','ap2','ap3']
env.password="hogehogepiyopiyo"

def tailall():
      sudo("tail -f  /var/log/httpd/access_log")

ap1とap2とap3のapacheアクセスログをtailします。 実行はこう

fab tailall

が、このスクリプトではおそらく期待する要件を満たすことは出来ません。 1つずつ解決していきます。

ホストに対して並列に実行してくれない

このままでは、ap1へtail→Ctrl+C→ap2へtail→Ctrl+C→ap3へtail という動作になってしまいます。 複数ホストのログを流し見するために並列にtailしたい場合、起動時にオプション -P--linewiseを足します。

fab -P --linewise taillall

こうすることで並列にtailが実行され、いい感じに流し見出来ます。 @parallel をつけても良いらしいです。

logrotateすると追従出来ない

これはfabricの問題ではなくてtailの問題。 tailf -f ではリモートファイルが切り替わった時に見失ってしまいます。 その場合は tailf もしくは tail -F を使うとlogrotateした際でもそのまま読み込む事ができます。

ctrl+Cで終了した際にリモートホストへtailプロセスが残ってしまう。

これは少し気づき辛い問題です。気づいた時には大量のtailが残ってたり。 上記のスクリプトを単純に実行し、ctrl+cを押して終了した場合、リモートホストにはtailしているプロセスがそのまま残ってしまっています。

[user@ap1 ~]$ ps aux|grep tail
root     31669  0.1  0.0 181928  3280 ?        Ss   19:39   0:00 sudo -S -p sudo password: /bin/bash -l -c tail -f /var/log/httpd/access_log

該当ホストにいってpsとかしてみないと気づかないので発覚した時は大分驚きます。 これを防ぐためには スクリプト内に env.remote_interrupt = Trueを追加します。

from fabric.api import sudo,env

env.remote_interrupt = True 
env.hosts=['ap1','ap2','ap3']
env.password="hogehogepiyopiyo"

def tailall():
      sudo("tail -f  /var/log/httpd/access_log")

これを追加することでCtrl+cしたら、remoteで実行しているコマンドも終了してくれます。

あとは色々キーボード処理などをよしなにキャッチしてあげればそこそこに使い勝手のあるスクリプトが出来上がります。

from fabric.api import sudo,env


env.remote_interrupt = True

env.hosts=['ap1','ap2','ap3']
env.password="hogehogepiyopiyo"


def tailall():
        try:
                sudo("tail -F /var/log/httpd/access_log")
        except  KeyboardInterrupt, e:
                pass
        return

fab -P --linewise tailall

ドメインを持ってないサーバーからMUTTでsoftbank/auへメールを送る

存在しないドメインをホスト名にしているサーバーからMUTTでメールを送ると、gmail/docomoなどでは問題ないがsoftbank/auなどでは拒否されてしまう。


This is the mail system at host hoge.yourserver.localdomain.

I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.

For further assistance, please send mail to postmaster.

If you do so, please include this problem report. You can
delete your own text from the attached returned message.

                   The mail system

<hogehohoge@i.softbank.jp>: host msv.softbank.jp[117.46.5.72] said: 553
    hoge.yourserver.localdomain. does not exist (in reply to MAIL FROM command)

理由としてはenvelope from addressが存在しないことによるもので、メールサーバーがエラーの際に送信するアドレスが実在(可視)するものでなければならない。 デフォルト設定のまま送信すると、サーバーのホスト名で送信され、この場合 hoge.yourserverというホスト名になる。 このホストはインターネット上に公開されているものではないのでエラーとして扱うようにsoftbankなどのサーバーが設定しているよう。

で、これを無視して強制で送信するには

set use_envelope_from = yes という設定をデフォルトなら~/.muttrc、設定ファイルを -fオプションで読み込ませているならそのファイル内に書けば良い。

envelope from addressは実際の送信者のアドレスなので適当な値にするのはアレですね

IPv6なTiarraにIPv4で接続出来なかった問題

atig.rb → tiarraLimeChatな構成。

atig.rbとtiarraはさくらVPSで動いてて、IPv6なアドレスを持っています。LimeChatは自分のMacBookPro.

とりあえずatig.rbは普通に起動。 TiarraIPv6で使うにはcpanモジュールを入れます。

cpan -i IO::Socket::INET6

で、起動してlocalhostのatig.rbにtiarraは接続出来ます。

が、ここからがハマりどころでした。

LimeChatからtiarraに接続すると、Connectedにはなるけどその後何も受信されない。 Resolve host address.... だかなんだかTiarraのログには出てるけどそれ以上待てど暮らせど。

そのVPS上にWeechatを入れて、接続するとつながります。

調べてみるとtiarraIPv6での解決がうまくいってない模様。

HANZUBON.jp » tiarra を IPv6 で動かした時に IPv4 なクライアントがつながらない問題

Tiarra自体がupdateしてくれる望みは薄そうなので、自分でこのパッチをあてたら接続出来るようになりました。 そろそろzncとかに移行するべきなんだろうか?