主夫ときどきプログラマ

データベース、Webエンジニアリング、コミュニティ、etc

スプーキーズの開発合宿に参加してきた

3月下旬に淡路島で行われたスプーキーズの開発合宿に参加してきました。 合宿所はこちらのLa Terrasse Awajiで、とても広くて美しい素晴らしい施設でした。

合宿の目的はこちらの2つ。

合宿を通じてメンバー同士が普段とは違ったコミュニケーションをとり親睦を深めること、その中で生まれる発想や試行錯誤をボードゲームという成果に落とし込むことの2つを目指しての2泊3日でした。

とまあ、合宿の詳しい内容はオフィシャルブログに譲るとして合宿の様子を写真中心で紹介しようと思います。

合宿所に到着。きれいなエントランスです。

f:id:masayuki14:20170401115011j:plain

早速メンバーが集まって今回の趣旨の説明。

f:id:masayuki14:20170331152049j:plain

自己紹介をして和やかなムード。

f:id:masayuki14:20170331153023j:plain

僕はガジェットが好きなんですよ。

f:id:masayuki14:20170331152759j:plain

僕はロクロを回すんですよ。

f:id:masayuki14:20170331153234j:plain

4人✕3チームに分かれてボードゲームを作りますよ!

f:id:masayuki14:20170331154042j:plain

f:id:masayuki14:20170331154414j:plain

さて、どうしようか。

f:id:masayuki14:20170331161435j:plain

コマ使うやつとか。

f:id:masayuki14:20170331180652j:plain

f:id:masayuki14:20170331173533j:plain

議論も白熱します。

f:id:masayuki14:20170331161505j:plain

f:id:masayuki14:20170331160412j:plain

とりあえずボードゲームで遊びますか。

f:id:masayuki14:20170331155845j:plain

えー、まじでー。

f:id:masayuki14:20170331161531j:plain

山盛りいちごで休憩。

f:id:masayuki14:20170331163734j:plain

薪がなくて使えなかった暖炉。

f:id:masayuki14:20170331163039j:plain

外はあいにくの雨模様。

f:id:masayuki14:20170331161727j:plain

廊下の奥には

f:id:masayuki14:20170331173712j:plain

きれいなベッドルーム。

f:id:masayuki14:20170331173826j:plain

ちょっと1人で考え中。

f:id:masayuki14:20170331180643j:plain

そろそろ夕食に行きますよ〜。

f:id:masayuki14:20170331174038j:plain

なんだか楽しそう。

f:id:masayuki14:20170331193842j:plain

淡路の海の幸、山の幸

f:id:masayuki14:20170331194747j:plain

f:id:masayuki14:20170331200536j:plain

夜が更けても煮詰まらない!

f:id:masayuki14:20170331220636j:plain

やっと形になってきたか!?

f:id:masayuki14:20170401004659j:plain

我々はもう出来たのでカタンで遊びますよ。

f:id:masayuki14:20170331234521j:plain

翌朝チームごとに制作したゲームを発表してテストプレイ。

f:id:masayuki14:20170401112008j:plain

プレゼンを聞く方も真剣。

f:id:masayuki14:20170401113024j:plain

コマを使ったパズルゲーム!!

f:id:masayuki14:20170401112721j:plain

頭をつかうゲームなのか!?

f:id:masayuki14:20170401113750j:plain

f:id:masayuki14:20170401113913j:plain

こちらのチームはアイドルがモチーフのよう。

f:id:masayuki14:20170401115743j:plain

f:id:masayuki14:20170401115247j:plain

次のチームはカードとチップを使ったゲーム

f:id:masayuki14:20170401124517j:plain

絵のクオリティが。

f:id:masayuki14:20170401123435j:plain

盛り上がってます!

f:id:masayuki14:20170401125543j:plain

ここで第一部が終了。 各人がおもしろいと思ったボードゲームに投票し、優勝チームにはご褒美となりました。

f:id:masayuki14:20170401131359j:plain

お昼休みを挟んでチーム替え。3人✕4チームに分かれて第二部の開始!

f:id:masayuki14:20170401151857j:plain

f:id:masayuki14:20170401151926j:plain

f:id:masayuki14:20170401151939j:plain

夜はデッキでバーベキュー!

f:id:masayuki14:20170401202656j:plain

食後に最後のプレゼンです!

f:id:masayuki14:20170401215725j:plain

盛り上がってますね。

f:id:masayuki14:20170401221125j:plain

f:id:masayuki14:20170401221143j:plain

第二部はカードゲームが多いようです。

f:id:masayuki14:20170401223238j:plain

f:id:masayuki14:20170401223551j:plain

f:id:masayuki14:20170401224857j:plain

優勝おめでとう! このあと夜遅くまで宴会&ボードゲームパーティーが続くのでした。

f:id:masayuki14:20170401231552j:plain

合宿おつかれさまでした!

f:id:masayuki14:20170402101928j:plain

Bash初心者から初級者へのステップアップするためのTips10選

CLIでいろいろとコマンドは使っているんだけど、bashスクリプトが書けるかというと・・・。 という人がbashの文法や機能を知って初級者へとレベルアップするためのTipsを紹介します。

1. ${変数}

シェルで変数を保持することができます。変数には文字列や数値を代入することができ、値を参照する場合は変数名の前に$を付けます。変数値は $VAL でも ${VAL} でも同じように参照出来ますが ${} の方が可読性も上がるのでおすすめです。

$ A=10
$ echo ${A}
10

変数に代入する時 = の前後にスペースを入れてはいけません。変数がコマンドとして解釈されてしまいます。

$ B = 10
bash: B: command not found

bashのバージョン4では ${VAL^} で単語の先頭を大文字に、 ${VAL^^} で単語全体を大文字に変換してくれます。

$ A='hello world'
$ echo ${A}
hello world
$ echo ${A^}
Hello world
$ echo ${A^^}
HELLO WORLD

変数の値は基本的にテキストとして扱われますので一般的なプログラミング言語のように四則演算はできません。

$ A=10
$ B=15
$ echo ${A} + ${B}
10 + 15

この様な場合は後述する算術式展開 $(( 計算式 )) を使います。

2. while read n; do [command] $n; done

パイプから受け取った標準入力を1つずつ変数に保持して引数として別のコマンドに渡したい。そんな時によく使う方法が while read ... のイディオムです。 X.txt Y.txt をそれぞれ X.txt.bak Y.txt.bak との差分をみたい場合、ワンライナー(1行スクリプト)で書くとこのようになります。

$ ls *.txt | while read f ; do diff ${f} ${f}.bak; done

# 通常の書き方
$ ls *.txt |
while read f
do
  diff ${f} ${f}.bak
done

ls の出力を1行ずつ読み込み変数 f に保持し diff コマンドの引数として与えています。 羊を100匹数える場合はこのようになります。

$ seq 100 | while read n; do sleep 1 ; echo "羊が${n}"; done

3. $(( 計算式 )) 算術式展開

$(( 計算式 )) は算術式展開と呼ばれるbashの機能でいろいろな計算ができます。四則演算はもちろんのこと論理積論理和などのビット演算もできます。

# 四則演算
$ A=10
$ B=15
$ echo $(( ${A} + ${B} ))
25
$ echo $(( ${A} * ${B} ))
150

# べき乗
$ echo $(( ${A} ** ${B} ))
1000000000000000
$ echo $(( 2 ** 16 ))
65536

# modulo
$ M=$(( ${A} % ${B} ))
$ echo ${M}
10
$ echo $(( 13 % 8 ))
5

# 論理積
$ echo $(( 15 & 4 )) # 1111 と 0100 の論理積
4

# 論理和
$ echo $(( 10 | 5 )) # 1010 と 0101 の論理和
15

# 排他的論理和
$ echo $(( 13 ^ 11 )) # 1101 と 1011 の排他的論理和
6

4. || && 終了ステータス判定

コマンドはその動作が成功すると「終了ステータス」として0を返します。失敗すると0以外の数字が返ります。直前のコマンドの終了のステータスは $? 変数に保持されます。

# wget コマンドの例
$ wget 'http://google.co.jp' 2> /dev/null
$ echo ${?}
0
$ wget 'http://foo.bar.baz.co.jp' 2> /dev/null
$ echo ${?}
4

0は成功のステータス、 4は失敗のステータスで Network failure. の意味です。 2> /dev/null標準エラー出力を捨てて表示されないようにしています。

&&|| はこの終了ステータスを判定するbash演算子です。&& で成功した時の処理、|| で失敗した時の処理を書きます。

$ wget 'http://google.co.jp' 2> /dev/null && echo 'success!' || echo 'failure...'
success!
$ wget 'http://foo.bar.baz.co.jp' 2> /dev/null && echo 'success!' || echo 'failure...'
failure...

gerp は何かがパターンマッチすれば0を、何もマッチしなければ1を返します。そこで || 演算子を使うと処理を分岐することができます。

$ ls -aF | grep 'git' || echo 'no git file or dir'
no git file or dir


$  ls -aF | grep 'git' || echo 'no git file or dir'
.git/
.gitignore

5. -- オプションの打ち止め

-Rf~ というようなディレクトリが何かの拍子にできてしまいまった場合どうすればよいでしょうか。

$ ls -F
-Rf -f/ ~/

まちがっても $ rm -Rf ~ なんてコマンドを打ってはいけません。 -Rf はオプションとして解釈されてしまいます。このような場合は -- を使います。-- は特別な引数でそれ以降のオプションが打ち止めとなります。

$ rm -- -Rf
$ rmdif -- -f

~ は通常ホームディレクトリと解釈さるので、 -- を利用しても意味がありません。シングルクォートでくくる、\ でエスケープする、./ でカレントディレクトリを明示するなどが必要です。

$ rm '~'
$ rm \~
$ rm ./~

6. ヒアドキュメント

複数行のテキストをプロセスの入力にします。 << 終了文字列 を記述し複数行の文字列を入力後に 終了文字列 を記載すると入力終了の合図となります。

$ cat -n << EOF
I have a pen.
I have a apple.
EOF
     1 I have a pen.
     2 I have a apple.

標準入力に流し込むので echo ではなく cat で出力しています。この出力をリダイレクトやパイプに渡す場合は、1行目に書く必要があります。

# 出力をリダイレクト
$ cat << EOF > output.txt
I have a pen.
I have a apple.
EOF

$ cat output.txt 
I have a pen.
I have a apple.
# パイプで渡す
$ cat << EOF | jq
[{
"name":"Matz","age":51,"from":"Japan"},
{"name":"Dhh","age":36,"from":"Denmark"}
]
EOF
[
  {
    "name": "Matz",
    "age": 29,
    "from": "Japan"
  },
  {
    "name": "Dhh",
    "age": 36,
    "from": "Denmark"
  }
]

標準入力に流し込むので while イディオムの入力としても利用できます。

$ while read n; do echo $(( ${n} * 2 )); done << EOF
1
2
3
4
5
EOF
2
4
6
8
10

7. <<< ヒアストリング

<<< の右側に書いた文字列や変数の値をコマンドの標準入力に流し込みます。 ヒアドキュメントと同じように扱えます。パイプとリダイレクトも通常通り利用できます。

$ cat <<< 'Hello World!!'
Hello World!!

$ JSON='[{
"name":"Matz","age":51,"from":"Japan"},
{"name":"Dhh","age":36,"from":"Denmark"}
]'

# パイプ |
$ jq . <<< ${JSON}} | grep -i 'matz'
    "name": "Matz",

# リダイレクト >
$ jq .[].name <<< ${JSON} > name.txt
$ cat name.txt
"Matz"
"Dhh"

8. $( コマンド ) コマンド置換

コマンドの実行結果を文字列として利用するための機能です。 コマンドの引数として展開したり引数に保持したりします。

# dateコマンドの結果が文字列に展開される
$ JSON="{\"time\":\"$(date +%s)\"}"
$ echo $JSON
{"time":"1489992386"}

# yamlファイルだけを抽出して処理
$ for f in $( find . -type f | grep '\.yml$' )
do
    [command] ${f} # 何らかの処理
done

9. $(< ファイル )コマンド置換

コマンド置換の拡張的な機能でファイルの中身に置き換えられます。

# cpコマンドを使わずbashの機能だけでファイルをコピー
$ echo "$(< /tmp/foo )" > /tmp/foo.bak

コマンドの処理結果を一時ファイルに保持することで可読性が向上します。

$ find . -type f | grep '\.yml$' > /tmp/yaml.list.txt
$ for f in $(< /tmp/yaml.list.txt )
do
    [command] ${f} # 何らかの処理
done

10. <( コマンド ) プロセス置換

コマンドの入出力をファイルとして扱う機能です。引数にファイルを受け取るコマンドの入力として利用できます。

# cat は引数としてファイルを受け取る
$ cat -n <( echo 'Hello World' ) <( echo 'Dreams come true' )
     1 Hello World
     2 Dreams come true
# ファイルリストの差分を diff で得る
$ ls
a.txt      c.txt      e.txt      h.txt       j.txt      l.txt      o.txt      q.txt
a.txt.bak  c.txt.bak  f.txt      i.txt       j.txt.bak  m.txt      o.txt.bak  q.txt.bak
b.txt      d.txt      g.txt      i.txt.bak   k.txt      n.txt      p.txt      r.txt
b.txt.bak  d.txt.bak  g.txt.bak  index.html  k.txt.bak  n.txt.bak  p.txt.bak  r.txt.bak

$ diff <( ls | grep '.txt$' | cut -d. -f1 ) <( ls | grep '.txt.bak$' | cut -d. -f1 )
5,6d4
< e
< f
8d5
< h
12,13d8
< l
< m

シェルプログラミング実用テクニック 入門bash 第3版 ソフトウェアデザイン 2016年 06 月号 ソフトウェアデザイン 2017年 01 月号

2017年の目標

年始からいろいろと考えていたことをまとめるためにも今年の目標を書き出します。

セルフブランディング

Rubykaigi2016に参加したことで改めて個人として活躍するには必要なことだと感じた。 まずは情熱プログラマーにもあるように「Googleで検索し最初の4ページのリンクだけを見てどんな人物だと想像するだろうか」という部分に注視して見ようと思う。 情熱プログラマーは改めて読むとほんとに良い本だ。

コミュニティでの登壇

勉強会やカンファレンスで登壇する。 3年後にはRubykaigiに登壇することを目指す。 オリンピックイヤーか・・・。

ブログ

Qiitaも含めてアウトプットを増やす。 最低でも月1回は書く。

OSSにコミット

GitHubでPullRequestを送る。 今年こそ!!

シェルプログラミング

シェル芸から入って bash が面白くなってきたのでシェルプログラミングでいろいろ出来るようになる。

Elixir

途中で止まってしまったプログラミングElixirをちゃんと読む。 演習問題もちゃんとやって手を動かす。

運用・監視まわり

Mackerelで独自のメトリクスを取りたい、という課題があるのでちゃんと勉強して達成する。 あわせてFuluentdとか使ってログ解析も出来るような基盤を考える。

新春bash書き初めをやった

SoftwareDesignの2017/1号の第1特集である新春bash書き初め シェル30本ノックをやった。
結果は 19/30 でまぁまぁの出来だと思う。
コマンドやbashについていろいろと新しい発見があったのでまとめておく。

各問題の自分なりの回答は GitHub においてある。
雑誌はこちら

コマンドについて

sed awk

抽出や変換など知れば知るほどなんでもできそうなコマンド。

  • sed -n '/開始パターン/,/終了パターン/p'
  • sed 'p' | sed '1d;$d' | paste
  • awk '{print}{fflush()}'

while read n; do [command] $n; done

繰り返しのイディオムで頻出。xargs とうまく使い分けよう。

openssl

暗号関連のいろんなことができるコマンド。使うことはほとんどなさそう。

crontab

コマンドというか @reboot コマンド起動時に1度、指定のコマンドを実行するという設定ができることを知った。

grep

grep -q . とすると、マッチの有無で終了ステータスが変わるので処理を分岐できる。
$ (何らかの処理) | grep -q . && (出力がある場合の処理) || (出力がない場合の処理) と出来る。
-q は標準出力に何も出さないオプション。

paste

それぞれのファイルの行を並列に結合する。

$ paste file1 file2
file1の1行目 file2の1行目
file1の2行目 file2の2行目
...

標準入力も扱える。

$ seq 1 10 | paste - -
1   2
3   4
5   6
7   8
9   10

file

ファイルの種類を推定してくれるコマンド。

tee

標準出力に出力しつつ、内容をファイルに保存する。
リダイレクトでは特権(sudo)が必要なファイルは書き込めないためteeを使うとうまくいく。
$ echo 'foo bar' | sudo tee special_file.txt

rev

反転してくれる。

$ seq 1 10 | xargs
1 2 3 4 5 6 7 8 9 10
$ seq 1 10 | xargs | rev
01 9 8 7 6 5 4 3 2 1

[

test コマンドの別名。if [ xxxx ]; でよく使われるのでオプションを覚えたほうが良い。

set env

set は現在のシェル変数、 env環境変数のみを出力する。

bashについて

${変数}

変数へ代入する時はスペースを入れてはいけない。
変数を使う時は$をつける。

$ n='hello world'
$ echo ${n}
hello world

|| && 終了ステータス判定

直前に実行したコマンド(処理)の終了ステータス($0)を判定するbash演算子
$ コマンド && コマンドが成功した時の処理 || コマンドが失敗した時の処理

<<< 標準入力へ流し込む

<<< の右側に書いた文字列や変数の値を標準入力に流し込む。

$ cat <<< 'hello world'
hello world
$ cat < 'hello world'
bash: no such file or directory: hello world

$(( 計算式 )) 算術式展開

いろいろな計算ができる。四則演算はもちろんのこと、論理和論理積、ビット演算も可能。

$ echo $(( 2 * 3 + 4 ))
10

$( コマンド ) コマンド置換

コマンドの実行結果を文字列として扱える。

$ for n in $( seq 1 5 ); do echo "羊が$n匹"; done
羊が1匹
羊が2匹
羊が3匹
羊が4匹
羊が5匹

:- 変数展開

難しいのでこちら
デフォルト値への置換ができる。

--

オプションの打ち止め。 $ mkdir -- -RF-RFというディレクトリが作成される。--以降はオプションと認識されなくなる。

$(<ファイル) コマンド置換2

コマンド置換の拡張的な機能で「ファイル」の中身に置き換えられる。

$ echo "$(<ファイル)" > foo$ cp ファイル foo と同じ。

<( コマンド ) プロセス置換

コマンドの入出力をファイルとして扱うことが出来る。

$ cat < <(echo 'hello world')
hello world

さいごに

各コマンドやbashの詳しい使い方や実例は雑誌を読んでくれ。

SoftwareDesign2017.01

2016年をふりかえる

Facebookにポストしてた2016年の目標をブログに移したのでそれをベースに2016年を振り返ります。

masayuki14.hatenablog.com

ひとつひとつ見ていきましょう。さほど意識しないで1年を過ごしてきたわけですが・・・。

2016年にたてた目標

Swift2

swift2を試す。iOsネイティブのアプリを作れるようになろう。年内にクソゲーがリリースできたらバンザイ\(^o^)/

2016年の目標 - masayuki14’s diary

宣言することは大事なもので、2月に参加したスプーキーズ沖縄合宿iOSアプリチームとなりSwiftにチャレンジすることとなりました。
夏頃からアプリ開発の案件にも参加することとなり年間通じて触れる機会に恵まれました。 Swiftの言語仕様はほぼ把握したのでコーディング自体には問題ありませんが UIKit 周りが全然わかってなくて、一人でアプリ開発することはまだまだできない感じです。

Redux

Reactで作ったアプリにReduxを導入する。

2016年の目標 - masayuki14’s diary

React 0.13 で開発したのでバージョンアップにも結構コストかかりそうだったし、サービス自体もあまり変更なく稼働していたのでそのまま。
Redux導入までには至りませんでした。今後も予定はありません。そして1年通じてほとんど React に触れませんでした。

Hubot

なんかつくる。くだらないものからやっていこう。みさわの画像出すとか。すでにありそうだけど。

2016年の目標 - masayuki14’s diary

忘れてください。ごめんなさい。

Meckerel

サーバーにMackerel入れてみる。APIコールして独自のメトリクスとりたい。

2016年の目標 - masayuki14’s diary

ごめんなさい。忘れてください。

ブログ

月に1回はブログを書く。ちゃんとアウトプットしよう。

2016年の目標 - masayuki14’s diary

月1とは言わずとも少しは書きました。せっかくなのでリンクを貼っておこう。

Rubyでメタプログラミング - 主夫ときどきプログラマ

スプーキーズの勉強会イベント一般公開します。 - スプーキーズの中の人。

おじさんの嫉妬は犬も喰わない - スプーキーズの中の人。

RubyKaigi2016 に行ってきました。 - 主夫ときどきプログラマ

暖かい季節にはモチベーションも上がるようです。

IPA試験

IPAの試験を受けてなんか合格したい。DBとネットワークあたりか。春の試験は受付中。

2016年の目標 - masayuki14’s diary

データベーススペシャリスト合格しました!おめでとう!
ネットワークスペシャリストは不合格でした!次回がんばろう!

OSSコミッタ

になろう。規模の大小は問わずGitHubでPullRequestを送ってみる。

2016年の目標 - masayuki14’s diary

https://github.com/ash1day/Copy-link-as-markdown/pull/3

知人のリポジトリですがPullRequest送ったのでこれでいいんだ!はじめの一歩はこんなもんだ!

コミュニティ活動

勉強会とか参加してみよう。

2016年の目標 - masayuki14’s diary

ブログにも書きましたがRubyKaigi2016にHelper Staff として参加しました。
今年1番の大きな出来事だと思っています。今後も京都や関西のコミュニティで活動を継続していきます。

総括

本当にやりたいと思っていることは目標にしてもしなくてもやるし、 そんなに思っても見ないことを目標にしてもあんまり達成しないのかな、という印象です。

とはいえそれほど思っても見ないことを達成するにはより目標とスケジュールを一緒に設定すればいいのかな、とも思います。 2017年もしっかり目標立てて1年後ふりかえれるように頑張ろう。