カメニッキ

カメとインコと釣りの人です

CloudFlareのソースIPにマッチするかもしれない正規表現

参考

'103\.21\.24[4-7]\.[0-9]{1,3}|103\.22\.20[0-3]\.[0-9]{1,3}|103\.31\.[4-7]\.[0-9]{1,3}|104\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3}|108\.162\.(19[2-9]|2[0-5][0-9])\.[0-9]{1,3}|131\.0\.7[2-5]\.[0-9]{1,3}|141\.101\.(6[4-9]|[7-9][0-9]|1[0-1][0-9]|12[0-7])\.[0-9]{1,3}|162\.15[8-9]\.[0-9]{1,3}\.[0-9]{1,3}|172\.(6[4-9]|7[0-1])\.[0-9]{1,3}\.[0-9]{1,3}|173\.245\.(4[8-9]|5[0-9]|6[0-3])\.[0-9]{1,3}|188\.114\.(9[6-9]|10[0-9]|11[0-1])\.[0-9]{1,3}|190\.93\.2[4-5][0-9]\.[0-9]{1,3}|197\.234\.24[0-3]\.[0-9]{1,3}|198\.41\.(12[8-9]|1[3-9][0-9]|2[0-5][0-9])\.[0-9]{1,3}|199\.27\.(12[8-9]|13[0-5])\.[0-9]{1,3}'

https://raw.githubusercontent.com/tap1ra/cloudflare-ip-regex/master/regex.txt

残件

  • cloudflare側のIPリストに変更があったときに自動反映
  • javascriptに食わせる作業が人力なので自動化

初めてOSS(Apacheモジュール)にPRだした

今回PRをだした対象


github.com

ApacheのVirtualHost単位でMaxClientsを設定することが可能な、Apacheモジュールです。 詳細は↓

ApacheのVirtualHost単位でMaxClientsを設定するApacheモジュールをOSS化 - 人間とウェブの未来

どんな機能を実装したか


MaxClientsの設定を有効にする時間帯を指定可能にする機能

本モジュールの利用を予定しているサーバの負荷は、常に一定ではなく高い時もあれば低い時もあります。 負荷の低い時間帯はMaxClientsを設定せず、自由に利用してもらうため、本機能の追加を行いました。

やったこと


途中色々アドバイスを受けながらあれこれ手戻ったりしてますが、簡略化するため一部改変してます。関数とか用語とか勘違いしてたら教えてあげてください やったこと、と言っても別に特別なことをしたわけではない

1. ソースを読む

mod_vhost_maxclients/mod_vhost_maxclients.c at master · matsumoto-r/mod_vhost_maxclients · GitHub

行数が短く、比較的読みやすいコードでした。
以下参考

上から構造体や関数定義などが並んでますが、とりあえず一番したから読む。
apxsを使用してApacheのモジュールを作成する場合、同じ形式になっているもよう。

#ifdef __APACHE24__
AP_DECLARE_MODULE(vhost_maxclients) = {
#else
module AP_MODULE_DECLARE_DATA vhost_maxclients_module = {
#endif
    STANDARD20_MODULE_STUFF, NULL,             /* create per-dir config structures     */
    NULL,                                      /* merge  per-dir    config structures  */
    # サーバ設定作成関数
    vhost_maxclients_create_server_config,     /* create per-server config
                                                  structures  */
    # サーバ設定関数
    vhost_maxclients_create_server_merge_conf, /* merge  per-server config structures  */
    # directiveの値を取得する関数
    vhost_maxclients_cmds,                     /* table of config file commands        */
    # フックするポイントを登録する関数
    vhost_maxclients_register_hooks};

それぞれ、登録された関数が何をやっているか見ました。

  • vhost_maxclients_create_server_config

    サーバ設定作成関数の名の通り、本モジュールで使用する設定値がデフォルト値とともに定義されています。

static void *vhost_maxclients_create_server_config(apr_pool_t *p, server_rec *s)
{
  vhost_maxclients_config *scfg = (vhost_maxclients_config *)apr_pcalloc(p, sizeof(*scfg));

  scfg->dryrun = -1;
  scfg->log_path = NULL;
  scfg->vhost_maxclients = 0;
  scfg->vhost_maxclients_log = 0;
  scfg->vhost_maxclients_per_ip = 0;
  scfg->ignore_extensions = apr_array_make(p, VHOST_MAXEXTENSIONS, sizeof(char *));

  return scfg;
}
  • vhost_maxclients_create_server_merge_conf
static void *vhost_maxclients_create_server_merge_conf(apr_pool_t *p, void *b, void *n)
{
  vhost_maxclients_config *base = (vhost_maxclients_config *)b;
  vhost_maxclients_config *new = (vhost_maxclients_config *)n;
  vhost_maxclients_config *scfg = (vhost_maxclients_config *)apr_pcalloc(p, sizeof(*scfg));

  if (new->dryrun > -1) {
    scfg->dryrun = new->dryrun;
  } else {
    scfg->dryrun = base->dryrun;
  }
  scfg->log_path = base->log_path;
  scfg->vhost_maxclients = new->vhost_maxclients;
  scfg->vhost_maxclients_log = new->vhost_maxclients_log;
  scfg->vhost_maxclients_per_ip = new->vhost_maxclients_per_ip;
  scfg->ignore_extensions = new->ignore_extensions;

  return scfg;
}
  • vhost_maxclients_cmds
    ディレクティブの定義をおこなっています。
    AP_INIT_TAKE1 を例にすると、directive指定は hoge 100 のように directive名 値 と名前の通り一個だけ取得する定義です。
    指定しているのは directive名 , directiveの値を変数にセットするための関数 mconfig(何かよく分かってない) , 定義されている場所, Help になります。
static command_rec vhost_maxclients_cmds[] = {
    AP_INIT_FLAG("VhostMaxClientsDryRun", set_vhost_maxclients_dryrun, NULL, ACCESS_CONF | RSRC_CONF,
                 "Enable dry-run which don't return 503, logging only: On / Off (default Off)"),
    AP_INIT_TAKE1("VhostMaxClients", set_vhost_maxclientsvhost, NULL, RSRC_CONF | ACCESS_CONF,
                  "maximum connections per Vhost"),
    AP_INIT_TAKE1("VhostMaxClientsLogOnly", set_vhost_maxclientsvhost_log, NULL, RSRC_CONF | ACCESS_CONF,
                  "loggign only: maximum connections per Vhost"),
    AP_INIT_TAKE1("VhostMaxClientsLogPath", set_vhost_maxclientsvhost_log_path, NULL, RSRC_CONF | ACCESS_CONF,
                  "logging file path instead of error_log"),
    AP_INIT_TAKE1("VhostMaxClientsPerIP", set_vhost_maxclientsvhost_perip, NULL, RSRC_CONF | ACCESS_CONF,
                  "maximum connections per IP of Vhost"),
    AP_INIT_ITERATE("IgnoreVhostMaxClientsExt", set_vhost_ignore_extensions, NULL, ACCESS_CONF | RSRC_CONF,
                    "Set Ignore Extensions."),
    {NULL},
};

directiveの値を変数にセットするための関数 を一個例に見ると set_vhost_ignore_extensions をちょっと見てみると、
バリデーションと値の取得をやってました。

static const char *set_vhost_ignore_extensions(cmd_parms *parms, void *mconfig, const char *arg)
{
  vhost_maxclients_config *scfg =
      (vhost_maxclients_config *)ap_get_module_config(parms->server->module_config, &vhost_maxclients_module);

  if (VHOST_MAXEXTENSIONS < scfg->ignore_extensions->nelts) {
    return "the number of ignore extensions exceeded";
  }

  *(const char **)apr_array_push(scfg->ignore_extensions) = arg;

  return NULL;
}
  • vhost_maxclients_register_hooks
    ハンドラをフックポイントに登録する関数
    人間とウェブの未来 - Apache hook関数 が参考になる。
    initルーチンとかを呼ぶ時にap_hook_post_config
    クライアントが認証受ける前に追加でアクセスチェックをしたい時にap_hook_access_checker
    をフックさせてます。本モジュールの役割的に ap_hook_access_checker(vhost_maxclients_handler, NULL, NULL, APR_HOOK_MIDDLE); が実際に制限させる処理をやってるぽいです。
static void vhost_maxclients_register_hooks(apr_pool_t *p)
{
  ap_hook_post_config(vhost_maxclients_init, NULL, NULL, APR_HOOK_MIDDLE);
  ap_hook_access_checker(vhost_maxclients_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

2. 書いてみる

  • vhost_maxclients_configに追加が必要なものを考える

    今回は制限する時間帯を指定したかったので、 制限開始する時間制限終了する時間 があればよさそうなので、vhost_maxclients_config構造体に2つ変数を追加

  unsigned int vhost_maxclients_time_from;
  unsigned int vhost_maxclients_time_to;
  • directiveから値を取得する

    2つ数字を渡せればいいので、1directive追加します。これで VhostMaxClientsTimeSlot 1100 2300 のようにconfに指定できます。 AP_INIT_TAKE2AP_INIT_TAKE1 の引数が一個増えた版。

AP_INIT_TAKE2("VhostMaxClientsTimeSlot", set_vhost_maxclients_time, NULL, RSRC_CONF | ACCESS_CONF,
                  "Time to enable the VhostMaxClients. (default 0:00 ~ 23:59)"),

TAKE2なのでarg1とarg2に一個目二個目の設定値が入ってくるので、時間のバリデーションをし、取得します。

static const char *set_vhost_maxclients_time(cmd_parms *parms, void *mconfig, const char *arg1, const char *arg2)
{
  vhost_maxclients_config *scfg =
      (vhost_maxclients_config *)ap_get_module_config(parms->server->module_config, &vhost_maxclients_module);

  scfg->vhost_maxclients_time_from = atoi(arg1);
  scfg->vhost_maxclients_time_to = atoi(arg2);

  if(scfg->vhost_maxclients_time_from < 0 || scfg->vhost_maxclients_time_from > 2359){
    return "VhostMaxClientsTimeSlot_From is invalid. should be set range 0 < VhostMaxClientsTimeSlot_From < 2359";
  }

  if (scfg->vhost_maxclients_time_to < 0 || scfg->vhost_maxclients_time_to > 2359){
    return "VhostMaxClientsTimeSlot_To is invalid. should be set range 0 < VhostMaxClientsTimeSlot_To < 2359";
  }

  return NULL;
}  
  • vhost_maxclients_handlerの処理中で時間を判定する処理の追加

    今回の機能は実際に制限をおこなうロジックの手前でやる必要があります。拡張子の判定処理の下あたりに入れます

  /* check time */
  if (check_time_slot(r->pool, scfg->vhost_maxclients_time_from, scfg->vhost_maxclients_time_to)) {
    return DECLINED;
  }

インラインでずらずら処理を書いてもいいのですが、汚いので関数に切り出します。
判定のやりかたは当初request_rec構造体のrequest_timeの値を利用しようとしましたが、apr_time_nowの値を使用することにしました。
apr_time_nowは現在時刻をUTC+マイクロ秒で返すので扱いにくいため、apr_time_exp_ltで人間向けに変換し、 をとってくっつけてintにしてます。
日をまたいだ指定( 23:00 ~ 2:00 など)のため、toよりfromが小さければ24時間プラスしてます。あとは現在時刻が指定した範囲内か判定します。

static int check_time_slot(apr_pool_t *p, unsigned int from, unsigned int to)
{
  unsigned int cur;

  apr_time_exp_t tm;
  apr_time_exp_lt(&tm, apr_time_now());
  cur = atoi(apr_psprintf(p, "%02d%02d", tm.tm_hour, tm.tm_min));

  if (from > to){
    to += 2400;
  }

  if ((from < cur) && (to > cur)){
    return 0;
  }

  return 1;
}

だいたい、上記のようなことをやりました。
あとは、以下のようにdirective指定し、想定通りの動作をするか確認します。

<VirtualHost *>
  DocumentRoot /var/www/html
  ServerName localhost
  VhostMaxClients 1
  VhostMaxClientsTimeSlot 2130 2300
</VirtualHost>

3. 検証

  • 正常動作 既存の同時接続数を制限する機能と時間の指定がどちらも動作するか確認します。
  • パフォーマンス 判定を一個入れたので、少なからず遅くなってるはずです。問題ないレベルかチェックします。見た感じ問題なさそう…
# 改修前のバージョン
[vagrant@localhost ~]$ ab -n100000 -c100  http://127.0.0.1/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests


Server Software:        Apache/2.2.15
Server Hostname:        127.0.0.1
Server Port:            80

Document Path:          /
Document Length:        17 bytes

Concurrency Level:      100
Time taken for tests:   16.434 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      28507125 bytes
HTML transferred:       1700425 bytes
Requests per second:    6084.97 [#/sec] (mean)
Time per request:       16.434 [ms] (mean)
Time per request:       0.164 [ms] (mean, across all concurrent requests)
Transfer rate:          1693.99 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    8   3.7      8      43
Processing:     1    9   3.6      8      45
Waiting:        0    7   3.5      7      43
Total:          1   16   4.2     15      57

Percentage of the requests served within a certain time (ms)
  50%     15
  66%     16
  75%     17
  80%     18
  90%     19
  95%     21
  98%     33
  99%     38
 100%     57 (longest request)

# 改修後のバージョン_1 制限を行う時間外
[vagrant@localhost ~]$ ab -n100000 -c100  http://127.0.0.1/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests


Server Software:        Apache/2.2.15
Server Hostname:        127.0.0.1
Server Port:            80

Document Path:          /
Document Length:        17 bytes

Concurrency Level:      100
Time taken for tests:   13.657 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      28508550 bytes
HTML transferred:       1700510 bytes
Requests per second:    7322.41 [#/sec] (mean)
Time per request:       13.657 [ms] (mean)
Time per request:       0.137 [ms] (mean, across all concurrent requests)
Transfer rate:          2038.59 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    4   3.2      5      15
Processing:     2    9   2.7      9      30
Waiting:        0    8   2.8      8      27
Total:          2   14   2.5     13      34

Percentage of the requests served within a certain time (ms)
  50%     13
  66%     14
  75%     15
  80%     15
  90%     17
  95%     18
  98%     20
  99%     22
 100%     34 (longest request)

# 改修後のバージョン_2 制限を行う時間内
[vagrant@localhost ~]$ ab -n100000 -c100  http://127.0.0.1/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests


Server Software:        Apache/2.2.15
Server Hostname:        127.0.0.1
Server Port:            80

Document Path:          /
Document Length:        17 bytes

Concurrency Level:      100
Time taken for tests:   15.214 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      28514250 bytes
HTML transferred:       1700850 bytes
Requests per second:    6572.97 [#/sec] (mean)
Time per request:       15.214 [ms] (mean)
Time per request:       0.152 [ms] (mean, across all concurrent requests)
Transfer rate:          1830.30 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    5   3.6      6      18
Processing:     2   10   3.0      9      39
Waiting:        0    9   2.9      9      35
Total:          2   15   3.1     15      43

Percentage of the requests served within a certain time (ms)
  50%     15
  66%     16
  75%     17
  80%     17
  90%     19
  95%     21
  98%     22
  99%     24
 100%     43 (longest request)

振り返り


  • apr_xxxxxが便利 Apache Portable Runtimeというサポートライブラリがあって、これが非常に便利なやつでした。
    たとえば cur = atoi(apr_psprintf(p, "%02d%02d", tm.tm_hour, tm.tm_min)); の部分
    当初は以下のように書いてました。

    c char hoge[5]; sprintf(hoge,"%02d%02d", tm.tm_hour, tm.tm_min));

    apr_psprintfを使用すると、hogeのようなメモリ割り当てが不要になり、request_rec構造体のプールを使わせることができます。
    戻り値をそのまま別の関数にくわせて、欲しい型でとれるから便利
    人間とウェブの未来 - apr_psprintfはかなり楽(apache2.x系)

  • 自分の英語雑過ぎる コメント無し

  • 普段コードを書いていないと基本的なことを忘れていく 関数名・変数名が長い、短くするとき意味がわからない。エラーメッセージに必要な内容が載ってない。 if(!((a!=b)&&(c<b)) みたいなこと書いちゃう。関係性の無い判定をelseifしちゃう。 酷い感じでした

  • githubOSSへPR出す際のお作法がわかってない コミットログ汚してしまって反省

  • httpdのソースを眺めながら書くとよい 変数の型や、利用する関数でソース中調べると色々助かる。コード量がおおいので、GNU Globalを使いました 人間とウェブの未来 - GNU GLOBALとvimで巨大なコードでも快適にコードリーディング - Forkwell

初めてcを書き、初めてOSSへPRを出すことができました。
cの入門書を眺めてただけだとしれなかったことがたくさんあり、やれてよかったと思います。
びびりまくってましたが、いざやってみるとみんな優しくて色々教えてくださったので、やってみたほうがいいです。

apacheのモジュール!? + cで書かれている... + OSSなんか怖い... = 不安 を克服していきたい

iTerm2 3.0にあげたらAlfredのWorkflowから起動できなくなったから対応

使っているのはこれ github.com

実行するとiTermを起動し、指定したホスト名へSSH接続する


動かなくなった原因はApplescriptの互換性が無いかららしい。iTermの公式ページに対応版コードが載ってたからそれを使うだけ。

手順

  1. Version 3 Beta - iTerm2 - Mac OS Terminal Replacement へアクセス
  2. Alfred SupportiTerm2 3.0 Alfred Script を開く
  3. 全文コピーして、以下に貼り付ける f:id:tapira:20160629111638p:plain

参考

http://harasou.github.io/2015/09/09/Alfred-iTerm2/harasou.github.io

最近覚えたシェルスクリプトの小ネタ

シェルスクリプトから教えていただいた。忘れないように書いとく

(追記)聞いて、自分の記憶した内容をそのまま書いちゃったので、ちゃんとマニュアル通りか確認してなかったので反省

$ man bash

目次

  • xargsでfunctionを叩く
  • 連想配列もどき
  • 変数間接参照
  • なんでもかんでもawkで整形しない
  • 文字列の末尾から数えて○文字目を△文字取り出す
  • 番外編:やたら if [ ]; then を使わない

Markdownで目次の書き方がわからんかった

xargsでfunctionを叩く


下の例だと find xxxx | xargs cp xxxx ってかけば良さそうでイマイチだけど、もっと複雑な処理やらせたいときに。

  • 前はこう書いてた
  #!/bin/bash

  for x in `find /var/www -name xxx`
  do
    cmd="cp -v /hoge/fuga/xxx $x"
    [[ `md5sum $x | awk '{print $1}'` != "xxxxxxxxxxxxxxxxxxxxxxx" ]] && eval $cmd | :
  done
  • xargsで5多重で同じことやらせる
#!/bin/bash

function sample() {
  cmd="cp -v /hoge/fuga/xxx $1"
  [[ `md5sum $1 | awk '{print $1}'` != "xxxxxxxxxxxxxxxxxxxxxxx" ]] && eval $cmd | :

}

# これしたらxargsから呼べることをしらなかった
export -f sample

find /var/www -name xxx | xargs -P5 -I{} bash -c "sample {}"

連想配列もどき


# 連想配列もどきのHを定義
declare -A H
H["a"]="682f7xxxxxxxxxxxxxxxxxxx0"
H["b"]="7808axxxxxxxxxxxxxxxxxxx2"
H["c"]="c6ba1xxxxxxxxxxxxxxxxxxx6"
H["d"]="64186xxxxxxxxxxxxxxxxxxxb"
H["e"]="50d1dxxxxxxxxxxxxxxxxxxxc"

for x in a b c d e
do
# とりだす
echo ${H["$x"]}
done

ちなみに、

  • こっちは配列見える
declare -A H
H["a"]="682f7xxxxxxxxxxxxxxxxxxx0"
H["b"]="7808axxxxxxxxxxxxxxxxxxx2"
H["c"]="c6ba1xxxxxxxxxxxxxxxxxxx6"
H["d"]="64186xxxxxxxxxxxxxxxxxxxb"
H["e"]="50d1dxxxxxxxxxxxxxxxxxxxc"

function sample(){
  # 682f7xxxxxxxxxxxxxxxxxxx0 
  echo ${H["a"]}
}

sample
  • こっちは配列見えない
#!/bin/bash

declare -A H
H["a"]="682f7xxxxxxxxxxxxxxxxxxx0"
H["b"]="7808axxxxxxxxxxxxxxxxxxx2"
H["c"]="c6ba1xxxxxxxxxxxxxxxxxxx6"
H["d"]="64186xxxxxxxxxxxxxxxxxxxb"
H["e"]="50d1dxxxxxxxxxxxxxxxxxxxc"

function sample(){
  # 682f7xxxxxxxxxxxxxxxxxxx0
  echo ${H["a"]}
  echo "hoge"
}
# ここで配列はexportされないらしいけど、あんまり詳しく調べてない。当たり前の動き?
export -f sample
find ~/test -type f  | xargs bash -c "sample"

変数間接参照


#!/bin/bash

var1="xxxxxxxxxxxxxxxx"
var2="yyyyyyyyyyyyyyyy"
var3="zzzzzzzzzzzzzzzz"

for i in `seq 1 3`
do  
  # 変数を使って作る変数名は一度変数に入れなきゃだめ
  tmp="var${i}"
  echo ${!tmp}
done

なんでもかんでもawkで整形しない


/home/hoge/fuga/piyo/php5.2.cgi のようなパスから、末尾の php5.2.cgi のみ抽出し、かつその値を利用して色々処理したい時に、つい以下のようなことを書いてた。

[root@hoge ~]# cat test.sh
#!/bin/bash

for x in `find ~/home/users/php-bin/ -path "*/.php-bin/php*.cgi"`
do
echo $x | awk -F/ '{print $10}'
done

このくらいのことをawk出してるとコストが高いので、bashの変数操作を使って以下の様に書く

[root@hoge ~]# cat test2.sh
#!/bin/bash

for x in `find ~/home/users/php-bin/ -path "*/.php-bin/php*.cgi"`
do
echo ${x##/*/}
done

すると

[root@hoge ~]# time ./test.sh
・・・
real    0m8.316s
user    0m2.367s
sys 0m7.828s

[root@hoge ~]# time ./test2.sh
・・・
real    0m0.763s
user    0m0.357s
sys 0m0.394s

圧倒的に早い!!!

捕捉 この例だと

find ~/home/users/php-bin/ -path "*/.php-bin/php*.cgi" | awk -F/ '{print $10}'

でいいけど、今回のこれは、①findしたパス②awkで整形した値両方を使用して、いろいろ処理する必要があって、forを利用してた

文字列の末尾から数えて○文字目を△文字取り出す

以下は乱暴な例ですが、 5.xx の値に応じて処理したい要件があった。 先頭の文字はファイルによってバラバラの長さのため、cutコマンドでは取得できないため、「末尾から何文字目」という指定をしたかった

[user ~/work/test]$ ll
total 0
-rw-r--r--  1 user  staff     0B  6 28 00:49 hogehogeho_ver5.2.sh
-rw-r--r--  1 user  staff     0B  6 28 00:49 xxxx.yyyy-abcdefghijk_ver5.2.sh
-rw-r--r--  1 user  staff     0B  6 28 00:49 xxxxxxxxxxxxxxxxxxxxxxxxxxx_ver5.2.sh
-rw-r--r--  1 user  staff     0B  6 28 00:49 yyyyyyyyyyyy-aaaaaaaaaaaaaaaa_ver5.3.sh
[user ~/work/test]$ for x in `find . -type f`
> do
> echo ${x:${#x}-4:1}
> done
2
2
2
3

番外編:やたら if [ ]; then を使わない


testコマンドを使うとフォークしてしまって大量に叩くとパフォーマンス悪いとのこと。

[PMAC226S ~/work]$ cat test.sh
#!/bin/bash

for i in `seq 1 1000000`
do
  if [ "$a" = "hoge" ]; then
    echo "hoge"
  else
    echo "fuga"
  fi
done

[PMAC226S ~/work]$ cat test2.sh
#!/bin/bash

for i in `seq 1 1000000`
do
  [[ "$a" = "hoge" ]]  && echo "hoge" || echo "fuga"
done

があった時、後者の方が結構はやい 

[PMAC226S ~/work]$ time ./test.sh
・・・
real    0m30.164s
user    0m20.777s
sys 0m2.917s

[PMAC226S ~/work]$ time ./test2.sh
・・・
real    0m25.246s
user    0m17.777s
sys 0m1.812s

第9回 コンテナ型仮想化の情報交換会@福岡で「Alpine Linux 入門した」という発表をした

人生初しゃべりでした。声が震えてた

speakerdeck.com

内容のレベルは正直低くて、まだまだ勉強不足感がありあり。
だけど、特性を知った上で計測をしつつ、良い使い道を模索できたので、そんなに悪い結果ではなかったと思いたい。


スライド内で使用したDockerfileはGithub

github.com


(追記)サイズの話ばかりしてたけど、小さいってことは余計なものが入ってないから、セキュアなのでした。 公式サイトにも記載あるし。