tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

【windows】windows7にDisk Usageコマンド(duコマンド)を使えるようにする - ディレクトリごとの容量を調べる

はじめに

もっぱらMacユーザですがたまにwindowsも使います。

windowsディレクトリ(ファイル)ごとの容量を調べたくなりました。
linuxmacではduというコマンドを使うと簡単に調べられます。

windowsではどうやって調べるんだろうと思ったら以下の方法で行うようです。

そこで今回はduコマンド入れるを行ってみました、というメモ

アジェンダ

  1. du(Disk Usage)のインストール
  2. 使う

1. du(Disk Usage)のインストール

Windows Sysinternalsからダウンロードして使います。

  • ファイルとディスク関連のユーティリティ リンクをクリック f:id:tweeeety:20170821175308p:plain

  • Disk Usage (DU) リンクをクリック f:id:tweeeety:20170821175319p:plain

  • Du のダウンロード リンクからダウンロード f:id:tweeeety:20170821175328p:plain

2. 使う

自分は何も考えずにデスクトップに落としましたが、落としたところまで移動するかパスを指定して実行すれば使えます。
何も指定しないとこんな感じ

C:\Users\tweeeety>c:Desktop\DU\du.exe

DU v1.6 - Directory disk usage reporter
Copyright (C) 2005-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

usage: c:Desktop\DU\du.exe [-c[t]] [-l <levels> | -n | -v] [-u] [-q] <directory>

   -c     Print output as CSV. Use -ct for tab delimiting.
          Use -nobanner to suppress banner.
   -l     Specify subdirectory depth of information (default is one level).
   -n     Do not recurse.
   -q     Quiet.
   -nobanner
          Do not display the startup banner and copyright message.
   -u     Count each instance of a hardlinked file.
   -v     Show size (in KB) of all subdirectories.

CSV output is formatted as:
Path,CurrentFileCount,CurrentFileSize,FileCount,DirectoryCount,DirectorySize,Dir
ectorySizeOnDisk
コマンド

こちらも表示されたまんまですが、以下のようにコマンドを打ちます。

c:Desktop\DU\du.exe [-c[t]] [-l | -n | -v] [-u] [-q]

Windows Sysinternals>Disk Usageに載ってますがオプションは以下です。

オプション 説明
-l 情報が必要なサブディレクトリの階層を指定します (既定ではすべてのレベルです)。
-n 再帰処理を行わないようにします。
-q バナーを出力しないようにします。
-u 同じものが複数回カウントされないようにします。
-v 中間ディレクトリの情報を表示します。
使用例

よく使うのは-l <levels>オプションでしょう。
-lを指定せずにディレクトリだけ指定すると、ディレクトリ以下のすべてのファイルがまで表示されてしまい見にくいです。

階層を指定するとその階層のディレクトリでまとめて容量を表示してくれます。

C:\Users\tweeeety>c:Desktop\DU\du.exe -l 1 C:\Users

DU v1.6 - Directory disk usage reporter
Copyright (C) 2005-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

      22,319  c:\users\Default
      57,777  c:\users\Public
     861,279  c:\users\tweeeety
      25,060  c:\users\sakura
Files:        1920
Directories:  1677
Size:         989,631,542 bytes
Size on disk: 1,002,791,104 bytes

おわり

duは使えたもののオプションと表示が違う(-h 容量を適当な単位で表示するようなものがない)ので、少し見にくいと感じました\(^o^)/

【go】golangのエラー処理メモ - ③. pkg/errorsでのエラーハンドリング

はじめに

goをさわって数ヶ月ですが、雰囲気では書けていたものの
errorやエラーハンドリングについてはもやもやしたままだったので自分理解メモの③

関連

この記事の関連です。

アジェンダ

  1. エラーハンドリングで困る事
  2. pkg/errorsでのエラーハンドリング(errors.Wrap)
  3. pkg/errorsでのエラーハンドリング(errors.Cause)

1. エラーハンドリングで困る事

main -> packageA.method -> packageB.method のように呼び出しを行っている場合、
packageB.methodで起きたエラーをpackageA.methodで拾ってmainにさらに返したいときがあります。

packageA.methodでのハンドリングによっては、
mainでなんのエラーだったかわかりにくくなるときがあります。

サンプル

ここでは main -> fuga.method -> hoge.method のように呼び出しているとします。

hoge.methodが返すエラーをfuga.method
ハンドリングしてさらにエラーを返します。

mainではerrrorかどうかをハンドリングします。

コード
package hoge

import "fmt"

type HogeSomethingError struct{}

func (f *HogeSomethingError) Error() string {
  return fmt.Sprintf("this is HogeSomethingError")
}

type HogeAnythingError struct{}

func (f *HogeAnythingError) Error() string {
  return fmt.Sprintf("this is HogeAnythingError")
}

func DoSomething() error {
  return &HogeSomethingError{}
}

func DoAnything() error {
  return &HogeAnythingError{}
}

func DoExciting(b bool) error {
  if b {
    return DoSomething()
  } else {
    return DoAnything()
  }
  return nil
}
package fuga

import (
  "errors"
  "go-error-handling_pkg-errors/package/hoge"
)

func DoExciting(b bool) error {
  err := hoge.DoExciting(b)

  if err != nil {
    switch err.(type) {

    case *hoge.HogeSomethingError:
      return errors.New("error1 at fuga")

    case *hoge.HogeAnythingError:
      return errors.New("error2 at fuga")

    }
  }

  return nil
}
package main

import (
  "fmt"
  "os"

  "go-error-handling_pkg-errors/package/fuga"
)

func main() {
  if err := fuga.DoExciting(false); err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
  }

  fmt.Println("main success")
}
出力
$ go run src/go-error-handling_pkg-errors/sample01/main.go 
error2 at fuga
exit status 1
困ること

mainでは、error2 at fuga と出力され、
エラーがあったことはわかるものの、hogeでエラーだったことがわかりません。

2. pkg/errorsでのエラーハンドリング(errors.Wrap)

そんな場合に pkg/errors でエラーハンドリングを行ってみます。

インストール

使う前にインストールしておきます。

pkg/errrosgo getなら以下のようにしてインストールできます。

go get -v github.com/pkg/errors

自分はglide環境なので、glide.yamlを以下のようにしてglide installしました。

package: go-error-handling_pkg-errors
import:
  - package: github.com/pkg/errors

サンプル

さきほどの fuga.methodpiyo.methodに置き換えて、
main -> piyo.method -> hoge.method と呼び出すようにします。

また、piyo.methodでは`pkg/errorsを使ってエラーハンドリングするようにしてみます。

コード
上記と同じです
package piyo

import (
  "go-error-handling_pkg-errors/package/hoge"

  "github.com/pkg/errors"
)

func DoExciting(b bool) error {
  err := hoge.DoExciting(b)

  if err != nil {
    switch err.(type) {

    case *hoge.HogeSomethingError:
      return errors.Wrap(err, "error1 at piyo")

    case *hoge.HogeAnythingError:
      return errors.Wrap(err, "error2 at piyo")

    }
  }

  return nil
}
package main

import (
  "fmt"
  "os"

  "go-error-handling_pkg-errors/package/piyo"
)

func main() {
  if err := piyo.DoExciting(false); err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
  }

  fmt.Println("main success")
}
出力
$ go run src/go-error-handling_pkg-errors/sample02/main.go 
error2 at piyo: this is HogeAnythingError
exit status 1
結果

error2 at piyoに続いて、大元の: this is HogeAnythingErrorも表示されました。

3. pkg/errorsでのエラーハンドリング(errors.Cause)

errors.Causeというのもあり、
これを使うと上記の例でいうとmainで原因となるエラーの型ハンドリングが可能となります。

mainだけ変更した例をのせておきます。

コード
package main

import (
  "fmt"
  "os"

  "github.com/pkg/errors"

  "go-error-handling_pkg-errors/package/hoge"
  "go-error-handling_pkg-errors/package/piyo"
)

func main() {
  if err := piyo.DoExciting(false); err != nil {
    switch errors.Cause(err).(type) {
    case *hoge.HogeSomethingError:
      fmt.Fprintln(os.Stderr, "case1 at main:", err)
    case *hoge.HogeAnythingError:
      fmt.Fprintln(os.Stderr, "case1 at main:", err)
    }
  }

  fmt.Println("main success")
}
出力
$ go run src/go-error-handling_pkg-errors/sample03/main.go 
case1 at main: error2 at piyo: this is HogeAnythingError
main success

おわり

こちらの参考でも言われてますが、
たしかにあまり深くWarpしまくるのも、という気もするので結局悩ましいループになりそう\(^o^)/

参考

【go】golangのエラー処理メモ - ②. 例外はないがエラーハンドリングはできるよ(インスタンスや型でハンドリング)

はじめに

goをさわって数ヶ月ですが、雰囲気では書けていたものの
errorやエラーハンドリングについてはもやもやしたままだったので自分理解メモの②

関連

この記事の関連です。

アジェンダ

  1. goのエラーについて
  2. 一番簡単なエラーハンドリング
  3. エラーハンドリングのパターン
  4. パターン1: errorの文字列で
  5. パターン2: errors.Newのインスタンス
  6. パターン3: カスタムエラーのインスタンス
  7. パターン4: カスタムエラーの型で

1. goのエラーについて

goのエラーについては以下に記載してみました。
【go】golangのエラー処理メモ - ①. errorとError型とカスタムErrorと

あえて項目にするまでもなかったけど前提として載せておきます

2. 一番簡単なエラーハンドリング

goは例外というモノがなく、
基本的には関数を呼び出した結果がエラーな場合はその場で処理します。

簡単なエラーハンドリング

その場で処理しちゃう例の一番簡単なものです。

サンプル

サンプルコード

package main

import (
  "errors"
  "fmt"
  "os"
)

func doSomething() error {
  return errors.New("doSomething is error.")
}

func main() {

  err := doSomething()

  // nilと比較してerrorオブジェクトが返ってたらエラーと見なす
  if err != nil {
    fmt.Println("main is failed")
    os.Exit(1)
  }

  fmt.Println("main is success")
}
出力
$ go run src/go-error-handling/sample01/main.go 
main is failed
exit status 1

エラーを無視する

また、エラーでも問題ない場合は_や単に何も受け取らないことで無視する事もできます。

サンプル

サンプルコード

package main

import (
  "errors"
  "fmt"
)

func doSomething() error {
  return errors.New("doSomething is error.")
}

func doHoge() {
  err := doSomething()

  // nilと比較してerrorオブジェクトが返ってたらエラーと見なす
  if err != nil {
    fmt.Println("doHoge is failed")
    return
  }

  // 処理を続ける
  fmt.Println("doHoge is success")
}

func doFuga() {

  // _ でerrorを無視する
  _ = doSomething()

  // 処理を続ける
  fmt.Println("doFuga is success")
}

func doPiyo() {
  // 単に受け取らないことも
  doSomething()

  // 処理を続ける
  fmt.Println("doPiyo is success")
}

func main() {

  doHoge()

  doFuga()

  doPiyo()

  fmt.Println("main is success")
}
出力
$ go run src/go-error-handling/sample02/main.go 
doHoge is failed
doFuga is success
doPiyo is success
main is success

3. エラーハンドリングのパターン

上記のような簡単なエラーハンドリングでも事足りる事はあります。

しかし、
実際は下位のmethodで発生したエラーをハンドリングしては上位に返して…
を繰り返すと困る事がでてきます。

自分は以下のような事が困りました。

  • 最上位でハンドリングで出力したものの根本原因がどこかわからない
  • エラーによって分岐したいがどのようにするのがベストプラクティスかわからない

エラーハンドリングのパーターンとしては以下のサイトが非常に参考になります。

参考サイトを参考に、
エラーハンドリングは以下のようなパターンで行う事ができます。

エラーハンドリングのパターン
  • パターン1: errorの文字列で
  • パターン2: errors.Newのインスタンス
  • パターン3: カスタムエラーのインスタンス
  • パターン4: カスタムエラーの型で

バッドノウハウなパターンも含まれてますが、
さっと書く使い捨てのscriptだったりではバッドノウハウパターンでも無いよりは良いかな、という印象です。

4. パターン1: errorの文字列で

errors.Newなりfmt.Errorfの文字列を受け取り側で比較するというものです。

単純ですがバッドノウハウとされているパターンです。

サンプル

サンプルコード

package main

import (
  "errors"
  "fmt"
  "os"
)

const (
  ERROR_MSG_01 = "doSomething is error. b is true"
  ERROR_MSG_02 = "doSomething is error. b is false"
)

func doSomething(b bool) error {

  if b {
    return errors.New(ERROR_MSG_01)

  } else {
    return errors.New(ERROR_MSG_02)
  }

  return nil
}

func main() {

  err := doSomething(true)

  if fmt.Sprintf("%s", err) == ERROR_MSG_01 {
    fmt.Println("ERROR: ERROR_MSG_01に応じた処理を行う")
    os.Exit(1)

  } else if fmt.Sprintf("%s", err) == ERROR_MSG_02 {
    fmt.Println("ERROR: ERROR_MSG_02に応じた処理を行う")
    os.Exit(1)
  }
  fmt.Println("main is success")
}
出力
$ go run src/go-error-handling/sample03/main.go 
ERROR: ERROR_MSG_01に応じた処理を行う
exit status 1
困る点

ハンドリング後、さらに呼び出し元に返そうとするととたんに困ります…

  // fmt.Errorfでさらに呼び出し元に返すとハンドリングできなく...
  if fmt.Sprintf("%s", err) == ERROR_MSG_01 {
    return fmt.Errorf("ERROR: err=%+v", err)
  }

5. パターン2: errors.Newのインスタンス

errors.Newのインスタンスで比較するパターンです。

osパッケージなんかでも使われてたりします
https://golang.org/src/os/error.go#L11

サンプル

サンプルコード

package main

import (
  "errors"
  "fmt"
  "os"
)

const (
  ERROR_MSG_01 = "doSomething is error. b is true"
  ERROR_MSG_02 = "doSomething is error. b is false"
)

var (
  ERROR_01 = errors.New(ERROR_MSG_01)
  ERROR_02 = errors.New(ERROR_MSG_02)
)

func doSomething(b bool) error {

  if b {
    return ERROR_01

  } else {
    return ERROR_02
  }

  return nil
}

func main() {

  err := doSomething(false)

  if err == ERROR_01 {
    fmt.Println("ERROR: インスタンスERROR_01に応じた処理を行う")
    os.Exit(1)

  } else if err == ERROR_02 {
    fmt.Println("ERROR: インスタンスERROR_02に応じた処理を行う")
    os.Exit(1)
  }
  fmt.Println("main is success")
}

コード自体はだいぶマシになった気はしてきます

出力
$ go run src/go-error-handling/sample04/main.go 
ERROR: インスタンスERROR_02に応じた処理を行う
exit status 1
困る点

パターン1と同様ですがハンドリングの結果、上位にエラーを返すときに困ります。

そのまま返すとどこでエラーだったのかわかりずらくなり、
fmt.Errorfなどで新規にインスタンスを作ってしまうと別物になってしまいます。

  // そのまま返し続けると結局どこのエラーだったのか...という感じに
  if err == ERROR_01 {
    return ERROR_01
  }
  // fmt.Errorfをかますと、違うインスタンスになってしまう
  if err == ERROR_01 {
    return fmt.Errorf("ERROR: err=%+v", ERROR_01)
  } 

6. パターン3: カスタムエラーのインスタンス

【go】golangのエラー処理メモ - ①. errorとError型とカスタムErrorと
でも触れたカスタムエラーを定義してそのインスタンスでハンドリングするパターンです。
1つのカスタムエラーを使い回してますが、カスタムエラー自体を複数用意しても良いです。

サンプル

サンプルコード

package main

import "fmt"

const (
  ERROR_MSG_01 = "doSomething is error. b is true"
  ERROR_MSG_02 = "doSomething is error. b is false"
)

type MyError struct {
  Msg  string
  Code int
}

func (err *MyError) Error() string {
  return fmt.Sprintf("%s, %d", err.Msg, err.Code)
}

var (
  MyError_01 = &MyError{Msg: "MyError_001 is occur", Code: 30001}
  MyError_02 = &MyError{Msg: "MyError_002 is occur", Code: 30002}
)

func doSomething(b bool) error {

  if b {
    return MyError_01

  } else {
    return MyError_02
  }

  return nil
}

func main() {

  err := doSomething(false)

  switch err {
  case MyError_01:
    fmt.Println("ERROR: インスタンスMyError_01に応じた処理")
    fmt.Printf("ERROR: %+v\n", err)

  case MyError_02:
    fmt.Println("ERROR: インスタンスMyError_02に応じた処理")
    fmt.Printf("ERROR: %+v\n", err)

    // ちなみにdoSomethingの返り値は
    // errorインターフェースであってMyError_01ではない。
    // ココに以下のようなコードは書けない
    //fmt.Printf("ERROR: Msg=%s, Code=%d", err.Msg, err.Code)
  }
  fmt.Println("main is success")
}
出力
$ go run src/go-error-handling/sample05/main.go 
ERROR: インスタンスMyError_02に応じた処理
ERROR: MyError_002 is occur, 30002
main is success
困る点

パターン2に同じ

7. パターン4: カスタムエラーの型で

カスタムエラーの型でハンドリングするパターンです。

err.(type)という記述をしますが、
これはerrorがinterface型のために行えるらしいです。(知らなかった)

また、これをConversion構文というらしいです。
https://golang.org/ref/spec#Conversions

サンプル

サンプルコード

package main

import "fmt"

type MyError_01 struct {
  Code int
}

func (err *MyError_01) Error() string {
  return fmt.Sprintf("this is MyError_01")
}

type MyError_02 struct {
  Code int
}

func (err *MyError_02) Error() string {
  return fmt.Sprintf("this is MyError_02")
}

func doSomething(b bool) error {

  if b {
    return &MyError_01{Code: 30001}

  } else {
    return &MyError_02{Code: 30002}
  }

  return nil
}

func main() {

  err := doSomething(false)

  switch e := err.(type) {
  case *MyError_01:
    fmt.Println("ERROR: MyError_01の型に応じた処理")
    fmt.Printf("ERROR: err=%+v, e=%+v, code=%d\n", err, e, e.Code)

  case *MyError_02:
    //fmt.Printf("ERROR: MyError_02のエラー, err=%+v, code=%d\n", e, e.Code)
    fmt.Println("ERROR: MyError_02の型に応じた処理")
    fmt.Printf("ERROR: err=%+v, e=%+v, code=%d\n", err, e, e.Code)
  }

  fmt.Println("main is success")
}
出力
$ go run src/go-error-handling/sample06/main.go 
ERROR: MyError_02の型に応じた処理
ERROR: err=this is MyError_02, e=this is MyError_02, code=30002
main is success
困る点

これまでの中では一番すっきりした感があります。

しかし、参考サイトまんまの受け売りですが、
このままerrorを上に上に伝搬させていくと
上位ロジックが全てのerrorを把握している必要がある、という感じ。

ではどうするのか

pkg/errorsを使うと良いらしい
が、長くなったのでまた次の記事にします。

これもまた参考サイトが非常に参考になりました!

おわり

errorについても奥が深い!\(^o^)/

【go】golangのエラー処理メモ - ①. errorとError型とカスタムErrorと

はじめに

goをさわって数ヶ月ですが、雰囲気では書けていたものの
errorやエラーハンドリングについてはもやもやしたままだったので自分理解メモの①

関連

この記事の関連です。

アジェンダ

  1. errorの基本の書き方
  2. Error型について
  3. 任意の文字列でError型を返す(errors.Newとfmt.Error)
  4. カスタムError

1. errorの基本の書き方

以下のコードがerrorについての基本です。

// Openに成功したらnil(エラー無し)が返される
// Openに失敗したらerror側の値が返却される
f, err := os.Open("filename.ext")
if err != nil {
    log.Fatal(err)
}

返されるerror変数とnilを比較することで操作が成功したか判断します。
上記で言えば if err != nil { です。

os.Openの定義は以下のようになっています。

func Open(name string) (file *File, err error)
https://golang.org/pkg/os/#Open

2. Error型について

errorはgoのビルトインのインターフェース型の1つです。

type error interface {
    Error() string
}

多くの内部パッケージにおいて使用されるerrorは
errorsパッケージ以下で実装されたプライベート構造体errorStringらしいです。

// Package errors implements functions to manipulate errors.
package errors

// New returns an error that formats as the given text.
func New(text string) error {
  return &errorString{text}
}

// errorString is a trivial implementation of error.
type errorString struct {
  s string
}

func (e *errorString) Error() string {
  return e.s
}

使う場合は、errors.Newを通して文字列をerrorStringに変換し
インターフェースerrorを満たすオブジェクトを得る、という感じになってます。

3. 任意の文字列でError型を返す(errors.Newとfmt.Error)

Error型について触れましたが、任意の文字列でerror型を返すには主に以下の2つがメジャーです。

用途としての大きな違いは、
fmt.Errorはフォーマットを指定したエラーを返せる ので
固定文字列でよければerrors.New、可変文字列を含めたければfmt.Errorという感じでしょうか。

以下で使ってみます。

errors.New

errors.Newに文字列を渡すだけです。

サンプル

https://github.com/tweeeety/go-error/blob/master/src/go-error/sample01/main.go

package main

import (
  "errors"
  "fmt"
)

func errorsNewSsample() error {
  err := errors.New("this is errors.New sample.")
  return err
}

func main() {
  err := errorsNewSsample()

  fmt.Println(err)
  fmt.Printf("%T\n", err)
}
出力
$ go run src/go-error/sample01/main.go 
this is errors.New sample.
*errors.errorString

fmt.Error

フォーマット文字列を渡せるので、変数の値を一緒に出したい場合などに使います。

サンプル

https://github.com/tweeeety/go-error/blob/master/src/go-error/sample02/main.go

package main

import (
  "fmt"
)

func fmtErrorfSsample(str string) error {
  err := fmt.Errorf("this is fmt.Errorf sample. str: %s", str)
  return err
}

func main() {
  err := fmtErrorfSsample("hogehoge")
  fmt.Println(err)
  fmt.Printf("%T\n", err)
}
出力
$ go run src/go-error/sample02/main.go 
this is fmt.Errorf sample. str: hogehoge
*errors.errorString

4. カスタムError

2. Error型についてで触れた通り
errorインターフェース満たすにはError()を実装すれば良いです。

この方法で任意のカスタムError型を作ります。

sample01/main.go
package main

import (
  "fmt"
)

// カスタムErrorの構造体
type MyError struct {
  Msg  string
  Code int
}

// error interfaceを実装
func (err *MyError) Error() string {
  return fmt.Sprintf("ERROR: %d %s", err.Code, err.Msg)
}

// 何かする処理
func doSomething() error {
  return &MyError{Msg: "doSomething is unexpected error", Code: 30001}
}

func main() {
  if err := doSomething(); err != nil {
    fmt.Println(err)
    fmt.Printf("%T\n", err)
  }
}
出力
$ go run src/go-error/sample03/main.go
ERROR: 30001 doSomething is unexpected error
*main.MyError

おわり

errorの扱いについてサラっとまとめました。
あまり長いと書くのも読むのも疲れるのでエラーハンドリングについては別記事でかきます\(^o^)/

参考

【mac】macでポート(port)を使用しているプロセス(pid)を調べる - 例) goapp serve

はじめに

localなmacで開発をしているとたまに既にport使用してるから立ち上げられんで!みたいなエラーがでる事があります。
そんなときにプロセスを調べるメモ

調べ方

先んじて結論ですが、lsof で調べます。
8080を使っているプロセスを知りたい時のコマンドです

sudo lsof -P -i:8080

こんな時 例

今回の例ですが、ポートを指定してlocalにサーバを立ち上げる とします。
もうちょっと具体的にすると、localなmacgolang x appengineの開発を行おうとしている、という例として進めます。

goapp serve hoge.yamlはlocalにサーバを立ち上げますが、
これはデフォルトで8080ポートを使用します。

いざ立ち上げようと思ったらこんなエラーが出ました。

$ goapp serve hoge.yaml 
INFO     2017-08-07 07:57:54,539 devappserver2.py:764] Skipping SDK update check.
INFO     2017-08-07 07:57:54,602 api_server.py:268] Starting API server at: http://localhost:62294
INFO     2017-08-07 07:57:54,606 api_server.py:700] Applying all pending transactions and saving the datastore
INFO     2017-08-07 07:57:54,606 api_server.py:703] Saving search indexes
Traceback (most recent call last):
  File "/usr/local/Cellar/app-engine-go-64/1.9.48/share/app-engine-go-64/dev_appserver.py", line 101, in <module>
    _run_file(__file__, globals())
  File "/usr/local/Cellar/app-engine-go-64/1.9.48/share/app-engine-go-64/dev_appserver.py", line 97, in _run_file
    execfile(_PATHS.script_file(script_name), globals_)
  File "/usr/local/Cellar/app-engine-go-64/1.9.48/share/app-engine-go-64/google/appengine/tools/devappserver2/devappserver2.py", line 1041, in <module>
    main()
  File "/usr/local/Cellar/app-engine-go-64/1.9.48/share/app-engine-go-64/google/appengine/tools/devappserver2/devappserver2.py", line 1029, in main
    dev_server.start(options)
  File "/usr/local/Cellar/app-engine-go-64/1.9.48/share/app-engine-go-64/google/appengine/tools/devappserver2/devappserver2.py", line 825, in start
    options.grpc_apis)
  File "/usr/local/Cellar/app-engine-go-64/1.9.48/share/app-engine-go-64/google/appengine/tools/devappserver2/dispatcher.py", line 196, in start
    _module.start()
  File "/usr/local/Cellar/app-engine-go-64/1.9.48/share/app-engine-go-64/google/appengine/tools/devappserver2/module.py", line 1198, in start
    self._balanced_module.start()
  File "/usr/local/Cellar/app-engine-go-64/1.9.48/share/app-engine-go-64/google/appengine/tools/devappserver2/wsgi_server.py", line 330, in start
    self._start_all_fixed_port(host_ports)
  File "/usr/local/Cellar/app-engine-go-64/1.9.48/share/app-engine-go-64/google/appengine/tools/devappserver2/wsgi_server.py", line 367, in _start_all_fixed_port
    raise BindError('Unable to bind %s:%s' % self.bind_addr)
google.appengine.tools.devappserver2.wsgi_server.BindError: Unable to bind localhost:8080
error while running dev_appserver.py: exit status 1

Unable to bind localhost:8080 とあるのでポートがすでに使われている可能性はあるもののterminal上どこでも立ち上げてる形跡はない…という状況です。

そのときのコマンド例

8080を使用しているプロセスを調べます。

$ sudo lsof -P -i:8080 
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
Python  58645 hoge   11u  IPv6 0x51abc044e9105fdb      0t0  TCP localhost:8080 (LISTEN)
Python  58645 hoge   12u  IPv4 0x51abc044e8ae2963      0t0  TCP localhost:8080 (LISTEN)

このプロセスに思い当たりがなければ思い切ってkillします。

$ sudo kill -9 58645 58645

再度立ち上げてみると無事立ち上がりました。めでたし

$ goapp serve local_production.yaml 
INFO     2017-08-07 08:47:58,533 devappserver2.py:764] Skipping SDK update check.
INFO     2017-08-07 08:47:58,611 api_server.py:268] Starting API server at: http://localhost:62971
INFO     2017-08-07 08:47:58,616 dispatcher.py:199] Starting module "borr" running at: http://localhost:8080
INFO     2017-08-07 08:47:58,621 admin_server.py:116] Starting admin server at: http://localhost:8000
WARNING  2017-08-07 08:47:58,621 devappserver2.py:836] No default module found. Ignoring.

オプション

申しわけ程度にlsofのオプションです。

オプション 説明
-c プロセス名を指定する
-i ネットワークソケットファイルを表示する
-n IPアドレスを表示する(名前解決しない)
-p プロセスIDを指定する
-P ポート番号をサービス名に変換しない

おわり

lsofはlinuxでも比較的よく使いますがオプション忘れては調べてるので備忘録的に書きました!

【SublimeText】jsHintとSublimeLinter-jshintを入れるメモ for mac

はじめに

久しぶりにsublimeが使いたい用途があり
今さらですがSublimeLinter-jshintを入れたので簡易手順メモ。

ちなみにES6などはESlintのほうが良いです。

アジェンダ

  1. jsHintをインストー
  2. jsHint/SublimeLinter/SublimeLinter-jshintについて
  3. SublimeLinterのインストー
  4. SublimeLinter-jshintのインストー
  5. 使ってみる

1. jsHintをインストー

jsHintのインストールはterminalコマンドで行います。

また、npmでインストールするのでnodeは必要ですが今回は省きます。
nodeとnpmが入っていれば以下のコマンドでjsHintインストールは終わりです。

# インストール
$ npm install -g jshint

# 確認
$ jshint -v
jshint v2.9.5

2. jsHint/SublimeLinter/SublimeLinter-jshintについて

休憩がてら自分用メモです。

jshintについて

jshintはコマンドで入れたように、SublimeLinter-jshint がなくても単体でjsHintとして動きます。

例えば以下コードを保存してjshintをコマンド実行する事もできます。

  • sample.js
(function(){
  "strict"
})();
  • 実行
# jsが入ってるディレクトリに対してjshint
$ jshint js_dir
js_dir/sample.js: line 2, col 11, Missing semicolon.

1 error

vimでも使えるので便利です。

SublimeTextについて

ここからはsublimeText上で行います。

SublimeTextでのパッケージインストールはPackage Controlが必要ですが、これも今回は省きます。

たまにしかSublimeを開かない自分用に
よく忘れるPackage Controlのショートカットも書いておきます。

Ctrl + Shift + p

SublimeLinterとSublimeLinter-jshintについて

SublimeLinterはリアルタイムにコードのエラーをチェックできるフレームワークのようなものです。
jsに限らず様々な言語のlinterとして動作しますが、言語ごとの設定を持っていません。

そこで、SublimeLinter-jshintというjavascript用のプラグインを追加で入れる事で
linter + javascriptな環境になります。

3. SublimeLinterのインストー

Package Controlから入れるだけです。

Ctrl + Shift + pでPackage Control開いてinstallと入力します。
Package Control: Install Packageを選択します。
f:id:tweeeety:20170725221240p:plain

ダイアログが開いたらSublimeLinterを選択してインストール完了です。 f:id:tweeeety:20170725221300p:plain

4. SublimeLinter-jshintのインストー

SublimeLinterと手順は同様です。

Ctrl + Shift + pでPackage Control開いてinstallと入力します。
Package Control: Install Packageを選択します。
ダイアログが開いたらSublimeLinter-jshintを選択してインストール完了です。

5. 使ってみる

使う前に、SublimeTextを再起動しておきます。
これをしないと動かないなーなんてことも。

適当なファイルを保存して開いてみると
先ほど書いたファイルを開いてみるとエラーの行数にオレンジのマークをしてくれます。 f:id:tweeeety:20170725221703p:plain

また、画面下部ににエラー内容も表示してくれます。

UTF-8, Error: Missing semicolon, Line2, Column11

おわり

久しぶりにsublime使いましたがパッケージのインストールもお手軽 \(^o^)/

【git】.gitignoreの書き方 - テンプレートを使うその3 - 任意のファイルを.gitignoreとして読み込む

はじめに

git管理化から特定のファイルなどを無視したければ.gitignoreに追加します。
しかもだいたいが適宜気づいたら、つどつど。

ただ、言語、フレームワーク、ツールなどのファイルは
新しいプロジェクトのたび x 適宜気づくたびに追加するのは面倒です。

そこで、
プロジェクトによらない.gitignoreしたいものはテンプレ化しておきたいですよね。
.gitignoreテンプレ化については以下を参考にしてみてください。

しかし、せっかくテンプレは手にいれたものの
vim使ってるの自分だけだしプロジェクトの.gitignoreを汚したくない…
そんなときのメモです。

やってみる

.gitignoreファイルはリポジトリ直下にある.gitignore以外にも
configのcore.excludesfileに任意のファイルを指定する事で無視してくれます。

なので、例えば$HOME/.gitignore_myというファイルを作り
そこに個人的なignoreリストを作成してconfigに登録しておくことで、
チーム共通のリポジトリ.gitignoreを汚さずにすみます

# 
$ cd `プロジェクトリポジトリ`

# ${プロジェクトディレクトリ}/.gitignoreの他に読み込むファイルを指定
$ git config --local core.excludesfile $HOME/.gitignore_my

# .git/configに追記されている
$ cat .git/config 
[core]
  ~ 省略 ~ 
  excludesfile = /Users/hoge/.gitignore_my
  ~ 省略 ~ 

こうしておけば
gitignore.iogiboので取得した自分だけが使ってるツールなどのgitignoreテンプレート設定を別にすることができます。

おわり

gitは長らく使ってるつもりでも知らない事が多いですね\(^o^)/