blogですかい

仕事、プライベートで学んだことなどを発信し、その内容がたとえ少数でも誰かの役に立ったらなら、それはとっても嬉しいなって

AWS LambdaでPerlのスクリプトを動かす

LambdaファンクションはNode.jsやJavaPythonで書くことができます。
では、Lambdaで動かしたい処理を、その3つの言語のどれで書かなければならないのかというと、そんなことはありません。

LambdaのインスタンスのOSはAmazon Linuxで、幾つかの言語の処理系がインストールされています。
例えばperl/bash/awk/luaなどを使用することが可能です。(他にも使用できる言語はもっとあると思います)

プログラムを作成する

Perlで書いたHello worldAWS Lambdaで動かしてみましょう。
perlスクリプト(hello.pl)と、perlを起動するためのNode.jsのスクリプト(index.js)を用意します。

Lambdaにアップロードするため、zipでまとめる。

$ zip -r hello-pl.zip hello.pl index.js

Lambdaにアップロード

f:id:oh-sky:20151019005550p:plain

実行結果

f:id:oh-sky:20151019005633p:plain

まとめ

このように、AWS LambdaではNode.js/Java/Python以外のプログラムを動かすことも可能です。
また、プログラムの処理系以外にも色々なアプリケーションがインストールされているので、それらを活用することで活用の幅が広がりそうです。

git rmやgit mvした状態をgit stash saveするのは避けたほうが良いかもしれない

git mvしたものをgit stashで保存・復原という操作をして気になったこと

$ git ls-files
hoge

$ git status
On branch master
nothing to commit, working directory clean

$ git mv hoge fuga
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        renamed:    hoge -> fuga


$ git stash save
Saved working directory and index state WIP on master: f93d032 first commit
HEAD is now at f93d032 first commit

$ git stash pop
Removing hoge
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   fuga

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    hoge

Dropped refs/stash@{0} (96680b45ca302e312299cab38c47802c07642913)

git stash save前とgit stash pop後で状態が変わっている!

$ git rm --cached hoge
rm 'hoge'

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        renamed:    hoge -> fuga

↑ファイルhogeをインデックスから削除すると、git stash save前と同じ状態に戻る。

$ git commit -m 'rename hoge to fuga'
[master 8c198ce] rename hoge to fuga
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename hoge => fuga (100%)

$ git rm fuga
rm 'fuga'

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    fuga

$ git stash save
Saved working directory and index state WIP on master: 8c198ce rename hoge to fuga
HEAD is now at 8c198ce rename hoge to fuga

$ git stash pop
Removing fuga
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    fuga

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (d0cca5c61ae3f9af7b1c9c09eb012081f87ffcf2)

git rmでファイルとインデックスを削除してgit stash save、その後git stash popすると、ファイルは消えているがインデックスは残っている。

$ git reset --hard HEAD
HEAD is now at 8c198ce rename hoge to fuga

$ git rm --cached fuga
rm 'fuga'

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    fuga

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        fuga

$ git stash save
Saved working directory and index state WIP on master: 8c198ce rename hoge to fuga
HEAD is now at 8c198ce rename hoge to fuga

$ git stash pop
Already up-to-date!
On branch master
nothing to commit, working directory clean
Dropped refs/stash@{0} (b39c66764d2bf85fa2b5409e31a9d322b0e72c95)

git rm --cachedでインデックスだけ削除しgit stash save、その後git stash popすると、git rm —cachedする前の状態に戻る。

上記の例ではgit stash saveの直後にgit stash popしているので問題は起こらないが、間に捜査を挟むとpop時に衝突が起こる場合もあると思う。
git rmgit mvした状態をstashで保存しておくということは今までしたことが無かったし、今後もすることがそうそう無いとは思うけれど、滅多にしないことだからこそ、気をつけたい。

最近使い方を知ったPHPの文字列関数

ltrim(string $str [, string $charlist])

$strの左端から連続する$charlistに含まれる文字を除去する

rtrim(string $str [, string $charlist])

$strの右端から連続する$charlistに含まれる文字を除去する

trim()は知っているけど、左右限定のものがあるとは知らなかった。 そういった処理を書こうとしたら、 preg_replace("/^[ \t\n\r\0\v/]+", '', $str) って書くと思う。

substr_count(string $haystack, string $needle)

$haystack$needleが何回出現するかを返す

php > echo substr_count('ccccccccc', 'cc');
4
php > echo substr_count('ccccccccc', 'ccc');
3

使い方はわかったけど、名前が悪い。なぜsubstr_というprefixなのかわからない。

substr_replace(mixed $string, mixed $replacement, mixed $start [, mixed $length])

$string$start位置から$lengthの長さの分の文字を$replacementに置き換える。$lengthを指定しない場合は、$replacementの長さ分の文字が置き換えられる。

php > $string = array('mutsuki', 'kuma');
php > $replacement = array('fumi', 'ta');
php > $start = array(0, 0);
php > $length = array(2, 2);
php > var_dump(substr_replace($string, $replacement, $start, $length));
array(2) {
  [0] =>
  string(7) "fumitsuki"
  [1] =>
  string(4) "tama"
}

strrev(string $str)

$strの文字列を逆順にして返す

php > echo strrev('yamamotoyama');
amayotomamay

何に使うんだこれ?

str_repeat(string $input, int $multiplier)

$input$multiplier回繰り返した文字列を返す

php > echo str_repeat('!すでのな', 3);
!すでのな!すでのな!すでのな

何に使うんだこれ?

strpad(string $input, int $pad_length [, string $pad_string = " "])

長さが$pad_lengthになるまで$string$pad_stringを繰り返し追加した文字列を返す

php > $ships = array(array('type' => 'HC', 'name' => 'Chokai'), array('type' => 'BC', 'name' => 'Kirishima'), array('type' => 'DD', 'name' => 'Mochizuki'));
php > foreach($ships as $ship) echo str_pad($ship['name'], 10) . $ship['type'] . "\n";
Chokai    HC
Kirishima BC
Mochizuki DD

get_meta_tags(string $filename)

指定したHTMLファイル(URL可)のmetaタグ情報を連装配列にして返す

php > var_dump(get_meta_tags('http://www.yahoo.co.jp'));
array(1) {
  'description' =>
  string(282) "日本最大級のポータルサイト。検索、オークション、ニュース、天気、スポーツ、メール、ショッピングなど多数のサービスを展開。あなたの生活をより豊かにする「課題解決エンジン」を目指していきます。"
}

strtok(string $str, string $token)

$str$tokenで分割し、分割してできた文字列を返す。2回目以降は引数に$tokenのみ指定する。

php > $str = '気合い,入れて,いきます';
php > $token = ',';
php > echo strtok($str, $token) . "!\n"; while ($tmpToken = strtok($token)) echo "{$tmpToken}!\n";
気合い!
入れて!
いきます!

初回と2度目以降で呼び出しが変わるって・・・誰が使うんだこの関数?

CakePHP3のShell

CakePHP Advent Calendar 2014 16日目

Shellの作成

src/Shell/ に作成。
例えば、 AiuraShell.php を下記のような内容で作成する。

デフォルトではAppShellクラスが無い点が、CakePHP2と異なる。
必要なら自分で作る。

上記のAiuraを実行すると下記のようになる。

Taskの作成

src/Shell/Task に作成。
例えば、KanakaTask.phpを下記のような内容で作成する。

Kanakaを実行するために、下記のようにAiuraShell.phpを変更する。

Aiuraを実行すると下記のようになる

コマンドからTaskを実行する

Kanakaタスクのmainメソッドを実行できるようにするため、AiuraShell.phpを下記のように変更する。

CakePHP2と違い、OptionParser::addSubCommand() でサブコマンドとして登録する必要がある。
また、デフォルトで呼ばれるTaskのメソッド名は execute() ではなく main()

実行すると下記のようになる。

ShellについてCakePHP2との違いまとめ

  • AppShellではなくShellを継承(必要であれば自分でAppShellを作る)
  • コマンドからTaskを実行できるようにするには、OptionParser::addSubcommand()でTaskをサブコマンドとして登録する
  • デフォルトで実行されるTaskのメソッドexecute()ではなくmain()

他にも違いはあるとは思いますが、とりあえず気になったのは上記の3点です。 (Modelの呼び出し方も変わっていますが、それについてはControllerと共通なので特に触れていません。)

日本酒は「生」が一番うまいと思います

日本酒 Advent Calendar 2014
6日目です

やっぱり、新鮮なものは「生」が一番うまい。

野菜も魚も肉も、そして日本酒も、旬な時期に生で食すのがBestなのです。

僕と生酒の出会い

僕が初めて生酒を体験したのは2014年2月23日。
しぼりたて祭り錦糸町2014』というイベントでした。

ちょうど、隣の駅である亀戸に引っ越したばかりで、なんとなく面白そうだと思い、行ってみたところ、飲む酒の全てがうまいのです。
それまで正直、日本酒は言うほど好きではなかった。
しかし、そのイベントで何種類もの生酒を飲んで衝撃を受けました。
それらはとても芳醇で、こんな素晴らしいお酒を飲める私はきっと特別な存在だと感じました。
今では私がKURAND会員。皆に勧めるのはもちろん生酒。
なぜなら皆さんもまた、特別な存在だからです。

KURANDとは

唐突に出てきた『KURAND』という固有名詞。
さぞかし気になっていることと存じます。

『KURAND』は、日本酒の定期購買サービス。
一月に一回(月末に)日本酒が届きます。
そして、届くお酒のほとんどは生酒です。
全国各地の酒蔵から毎月生酒が届く。
なんて素晴らしいサービスなんでしょう。

KURANDはお酒だけでなく、おつまみや酒粕、酒器などが同時に届きます。
おつまみは、その月に送られてくるお酒の酒蔵の、地元のものであることが多いです。
合わないわけがない。

また、KURANDの会員になると、KURANDが主催する日本酒のイベントに割引で参加できます。
僕が初めて参加した『しぼりたて祭り錦糸町2014』も、KURANDのイベントでした。

ステマでは無いアピール

ここまでKURAND推しだと、関係者だと思われるかもしれません。
関係者では無いことをアピールするために、ひとつ要望を申し上げます。
おつまみもいいけど、酒器をもっとください。

4月に登録してからこれまで、おまけが酒器であったことが一度しかありません。
たまにはカタチに残るものが欲しいのです。 芳醇な生酒を飲むのに適した、ワイングラスであったりすると嬉しいです。

何卒

Jenkinsの移行作業(Debian)

移行用のプラグインもあるっぽいけれど、Jenkinsのホームディレクトリを丸々コピーでいけるようなので、似たような環境(jenkinsのユーザIDが変わらないような)であれば、丸々コピーが簡単です。

移行元にて

$ cd /var/lib/jenkins
$ sudo tar -zcf /tmp/jenkinsbackup.tar.gz .

もしワークスペースを除外したければ
tar -zcf /tmp/jenkinsbackup.tar.gz --exclude workspace .

ftpなりscpなりで、移行先にjenkinsbackup.tar.gzを移動する。

移行先にて

$ cd /var/lib/jenkins
$ sudo tar -xcpf ~/jenkinsbackup.tar.gz
$ sudo service jenkins restart

Ubuntu14.04LTS + Nginx + HHVMでWebアプリを動かす準備

少々出遅れた感アリですが、HHVM(というかHack)の勉強を始めようと思い、環境を作りました。
備忘録として、やったことをここに書き残します。

Ubuntu 14.04 LTSの環境は用意されている前提で

Nginxのインストール

$ sudo apt-get update
$ sudo apt-get install nginx

HHVMのインストール

標準のリポジトリには無いので、公式Wikiに従い追加します。

$ wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add -
$ echo deb http://dl.hhvm.com/ubuntu trusty main | sudo tee /etc/apt/sources.list.d/hhvm.list
$ sudo apt-get update
$ sudo apt-get install hhvm

NginxとHHVMを連携するための設定

/etc/nginx/hhvm.conf

デフォルトのままで良いです

location ~ \.(hh|php)$ {
    fastcgi_keep_conn on;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

/etc/nginx/sites-available/hello-hhvm.conf

新規に作成します(ファイル名、ドキュメントルートは任意で)

server {
        listen 80 default_server;

        root /var/www;
        index index.php;

        server_name localhost;

        include hhvm.conf;

}

設定を有効にするためにソフトリンクを作る(Debian系特有の儀式)

/etc/nginx/sites-enable/に、先ほど作成した設定ファイルへのリンクを作成します。 また、デフォルトの設定ファイルへのリンクを削除します。

$ sudo ln -s /etc/nginx/sites-available/hello-hhvm.conf /etc/nginx/sites-enabled/
$ sudo rm /etc/nginx/sites-enabled/default

NginxとHHVMデーモンの起動

$ sudo service nginx start
$ sudo service hhvm start

HHVMデーモンの自動起動設定

Debian系はupdate-rc.dコマンドを使用します。RedHat系だったらchkconfigですね。

$ sudo update-rc.d hhvm defaults

/var/www/index.php

HelloWorldアプリを作成します。

<?hh
echo 'Hello HHVM!';

これで、Webブラウザでhttp://サーバ名orIPアドレス/index.phpにアクセスしてみて「Hello HHVM!」と表示されれば成功です。