それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

nginx の fastcgi_cache_lock が便利

nginx → php-fpm への同時リクエスト数制御

nginx の設定をしていて 負荷をかけたときに、nginx → php-fpm へ同じURLのリクエストが1本しか飛ばないので不思議だった。

fastcgi_cache_lock

fastcgi_cache_lock

When enabled, only one request at a time will be allowed to populate a new cache element

nginx から fcgi で キャッシュをしていると、複数同時に、リクエストが来ても最初の一発でキャッシュが生成されるまで、次のリクエストのレスポンスは待たされる。

なるほどね。キャッシュが生成リクエストを絞ってくれるのでこれはいいな。

大量に画像を生成してインデックスしてくれるので写真のアルバム系アプリやブログ系など、ユーザーごとに内容が変わらなくて、かつ生成に時間がかかるものはとっても負荷がおちるし、作成も同時接続数を考えずにバンバンリクエスト投げればいいっていうHTTPの根本をいじらなくていいのは素敵だと思った。

参考資料

http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_lock_age

itunesで取得したバックアップの場所(path)を調べてバックアップを取得する

iTunesiPhoneのバックアップを取ったものを保存しておきたい。

iTunesで取得したバックアップを、どこかストレージに放り込んで保存しておきたい。

バックアップの場所をぱぱっと調べる方法

iTunes からバックアップ一覧を閲覧して 右クリック をすることでファイルの場所が表示される。

f:id:takuya_1st:20180626161908p:plain

保存されていた場所

わたしのMac場合、次の場所に保存されていました。

~/Library/Application Support/MobileSync/Backup

なんでこんなことをするのか、バックアップを取得して世代管理をするとなると、iCloudでは物足りないし、MacやPCに保存していたらデータ容量が大きくなるので管理がめんどくさい。

iTunesに書き出す利点

バックアップからの復元操作が早い。でもAppsのバックアップを取得できなくなってしまったので、メリットはなくなったかもしれない。復元後にアプリがAppleApp Store 経由のインストールに限られるので、時間が半端なくかかるようになってしまった。

それでもUSB経由はクラウド経由より早い気がする。

時間は無限じゃないんだけどなぁ。Appの再インストールで時間食うの辛い。

pip インストールを自動でやる。

pip を自動で実行すると Yes / No を聞かれる

DockerileでCOPYしたシェルスクリプトからpip をインストールしてたら、割とめんどくさい事になった。

Proceed (y/n)? Exception:
Traceback (most recent call last):
(
    return ask('Proceed (y/n)? ', ('y', 'n')) == 'y'
    response = input(message)
EOFError: EOF when reading a line

対策 : install 時は

yes | pip install package-name

対策: uninstall は

pip uninstall --yes package-name

これ、揺れてるんですね。めんどくさいのではないか。

参考資料

https://stackoverflow.com/questions/4536103/how-can-i-upgrade-specific-packages-using-pip-and-a-requirements-file

lvm でディスクのサイズをパパッと変更するコマンド

lv で管理しているボリュームのサイズは簡単に増減できるんですね。

ディスクのサイズを増やすとき

sudo lvextend --resizefs --size +10G /dev/mapper/my-root

ディスクのサイズを減らすとき

sudo lvreduce --resizefs --size -10G /dev/mapper/my-root

resizefs

オプションにresizefs をつけるとLVMのディスクのファイルシステムのフォーマットにあわせて、増減してくれる。わーい。

便利

2018-06-18 アレコレ試した感じだと、マウントしたままでも行けるっぽい。LVMに依る管理は完成してるな。

lvm でオンラインリサイズできたのか

ディスクのボリュームを動的に変更する。

ハードディスクやSSDのサイズを動的に変えるには、いちいちリカバリーモードで起動するとか、ReadOnlyで起動するとか、ライブCDで起動するかそういう事が必要だと思ってた。

むしろ思い込んでいた。

LVMでリサイズして遊んでて、あれ、もしかしてマウントしたままリサイズできるんじゃね?とおもって試してた。

/ root をマウントした状態でリサイズを命令しったった

まいかい、mount を外してたけど、あそんでてコマンドミスって、あ、、、やらかしたともったら、そのままリサイズされて完了した。

takuya@:/$ sudo lvextend --resizefs --size +10G /dev/mapper/my-root
  Size of logical volume my/root changed from 40.00 GiB (10240 extents) to 50.00 GiB (12800 extents).
  Logical volume my/root successfully resized.
resize2fs 1.43.4 (31-Jan-2017)
Filesystem at /dev/mapper/my-root is mounted on /; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 4
The filesystem on /dev/mapper/my-root is now 13107200 (4k) blocks long.

え、うそ。実行完了されちゃった。 VGには100GBほど空き容量がある状態です。10GBは確保できるのですが、実行できるんだ。。。

結果を見てみる。

あ、、、ほんとに増えてる。

takuya@:/$ df -h
ファイルシス           サイズ  使用  残り 使用% マウント位置
/dev/mapper/my-root     50G   17G   31G   35% /

LVS のビフォー・アフターも比較してみる。

ビフォーアフターの状態がこれ。

before

takuya@:~$ sudo lvs
  LV    VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root  my -wi-ao---- 40.00g

after

takuya@:/$ sudo lvs
  LV    VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root  my -wi-ao---- 50.00g

もうLVMでいいじゃん。

ファイルシステムやmapperにはアレコレあるけど容量の管理は もうLVM で十分な気がしました

参考資料

bashでCtrl-Cなどシグナルをトラップ(検出)して終了時の処理を書く

bashで ctrl-C の検出をするには

bash でCtr-C の検出をする必要がある利用場面がある。たとえば、時間のかかる処理を書いていて途中で止めたいとか、スクリプトを作っていて中間ファイルを確実に消したいとか、Ctr-Cの強制終了で止めたときに「なにか処理」を実施したいことがったります。

trap を使う。

trap を使うことで実現ができる

#!/usr/bin/env bash 

trap 'echo Trapped; echo end' 2

sleep 10

trap にわたすのは、文字列ではなく「コマンド」

先の例であれば、文字列を渡していますが、正確には「コマンド(として実行できる文字)」を渡しています。

そのため、関数を作って次のようなこともできます。

#!/usr/bin/env/sh
function on_signal_interrupt( ){
  echo interrupted. shutdown ;
}

trap on_signal_interrupt 2

sleep 60

ありがちなミス。

trap を使おうとしてありがちなミスが次の例です。

trap で関数が登録する前に、時間のかかる処理を書いても当然実行されません。

#!/usr/bin/env bash 

sleep 10 ## ここで時間のかかる処理。→ Ctr-C

trap 'echo Trapped; echo end' 2 # ←実行されない

ソースファイルにコードを追記するので、ついつい末尾に追加してやらかすことは結構あるので注意。

複数のシグナルをまとめてキャッチする。

trap  "echo trapped " 1 2 3 4 5 

まとめて書けばまとめてトラップしてキャッチできる。

まとめて書いても、どのシグナルか区別できない・・・

シグナルをまとめて受け取ったとしても、関数内でそれを区別できないっぽいです。

#!/usr/bin/env bash 

function on_siginal( ){ 

  echo 
  echo arguments is ...
  echo $@
  echo signal_traoped
}
trap on_siginal 1 2 3 

sleep 10

実行結果

takuya@Desktop$ bash signal_trap.sh
^C
arguments is ...

signal_traoped

まとめて受け取ってCASEで分岐出たら便利なのにね。できなさそう。

trap の使い方の調べ方

trap は、 シェルの組み込みコマンドなので、man ではなく、help で使い方を確認することができます。

takuya@Desktop$ help trap
trap: trap [-lp] [[arg] signal_spec ...]
    シグナルまたは他のイベントをトラップします。

    シェルがシグナルを受け取るか他の条件が発生した時に実行されるハンドラーを
    定義および有効化します。

    ARG はシグナル SIGNAL_SPEC を受け取った時に読み込まれ実行されるコマンド
    です。もし ARG が無い (かつシグナル SIGNAL_SPEC が与えられた場合) または
    `-' の場合、各指定したシグナルはオリジナルの値にリセットされます。
    ARG が NULL 文字列の場合、各シグナル SIGNAL_SPEC はシェルにおよび起動さ
    れたコマンドによって無視されます。

    もし SIGNAL_SPEC が EXIT (0) の場合、ARG がシェルの終了時に実行されます。
    もし SIGNAL_SPEC が DEBUG の場合 ARG は単に毎回コマンドの前に実行されます。
    もし SIGNAL_SPEC が RETURN の場合 ARG はシェル関数または . か source に
    よって実行されたスクリプトが終了した時に実行されます。 SIGNAL_SPEC が ERR
    の場合、-e オプションが有効な場合にシェルが終了するようなコマンド失敗が発
    生するたびに実行されます。

    もし引数が与えられない場合、 trap は各シグナルに割り当てられたコマンドの
    一覧を表示します。

    オプション:
      -l    シグナル名とシグナル番号の対応一覧を表示します
      -p    各 SIGNAL_SPEC に関連づけられた trap コマンドを表示します

    各 SIGNAL_SPEC は <signal.h> にあるシグナル名かシグナル番号です。シグ
    ナル名は大文字小文字を区別しません。また SIG 接頭辞はオプションです。
    シグナルはシェルに対して "kill -signal $$" で送ることができます。

    終了ステータス:
    SIGSPEC が無効か、無効なオプションを与えられない限り成功を返します。

wait: trap と合わせて知っておくと便利なBashの関数

そもそもTrapをどう使えばいいのか、疑問に思うこともあるけど、wait で他のプロセスを待ち合わせてるときとかに便利かもしれないですね。 wait のマニュアルはコチラ。

takuya@Desktop$ help wait
wait: wait [-n] [id ...]
    ジョブの実行完了を待ち、終了ステータスを返します。

    ID で識別される各プロセス (プロセスID または ジョブ指定) を待ち、その終了
    ステータスを返します。ID が与えられない場合、現在アクティブな全ての子プ
    ロセスを待ち 0 を返します。ID がジョブ指定の場合ジョブのパイプラインに
    ある全てのプロセスを待ちます。

    終了ステータス:
    最後の ID の終了ステータスを返します。IDが無効であるか、無効なオプ
    ションが与えられた場合には失敗を返します。

シグナル一覧

シグナルは、man signal で一覧を見ることができる。

    No    Name         Default Action       Description
     1     SIGHUP       terminate process    terminal line hangup
     2     SIGINT       terminate process    interrupt program
     3     SIGQUIT      create core image    quit program
     4     SIGILL       create core image    illegal instruction
     5     SIGTRAP      create core image    trace trap
     6     SIGABRT      create core image    abort program (formerly SIGIOT)
     7     SIGEMT       create core image    emulate instruction executed
     8     SIGFPE       create core image    floating-point exception
     9     SIGKILL      terminate process    kill program
     10    SIGBUS       create core image    bus error
     11    SIGSEGV      create core image    segmentation violation
     12    SIGSYS       create core image    non-existent system call invoked
     13    SIGPIPE      terminate process    write on a pipe with no reader
     14    SIGALRM      terminate process    real-time timer expired
     15    SIGTERM      terminate process    software termination signal
     16    SIGURG       discard signal       urgent condition present on socket
     17    SIGSTOP      stop process         stop (cannot be caught or ignored)
     18    SIGTSTP      stop process         stop signal generated from keyboard
     19    SIGCONT      discard signal       continue after stop
     20    SIGCHLD      discard signal       child status has changed
     21    SIGTTIN      stop process         background read attempted from control terminal
     22    SIGTTOU      stop process         background write attempted to control terminal
     23    SIGIO        discard signal       I/O is possible on a descriptor (see fcntl(2))
     24    SIGXCPU      terminate process    cpu time limit exceeded (see setrlimit(2))
     25    SIGXFSZ      terminate process    file size limit exceeded (see setrlimit(2))
     26    SIGVTALRM    terminate process    virtual time alarm (see setitimer(2))
     27    SIGPROF      terminate process    profiling timer alarm (see setitimer(2))
     28    SIGWINCH     discard signal       Window size change
     29    SIGINFO      discard signal       status request from keyboard
     30    SIGUSR1      terminate process    User defined signal 1
     31    SIGUSR2      terminate process    User defined signal 2

参考資料

partprobeが見つからない。

partprobe を実行しようとしたら

コマンドが見つからない。 partprobe command not found .になった。

partprobe ずっと使ってて、いつ入れたか、どのパッケージと入れたかわかない。

parted

ぐぐったら、 partprobe は parted についてくる

sudo apt install parted 

これでpartprobeが使える。

参考資料

https://www.linuxquestions.org/questions/debian-26/partprobe-for-debian-529726/

文字の実体参照と実コードを変換する

文字の実体参照と実コード(文字)を変換する。

sednkf でもできる ruby なら出来るんだけど

>>> escaped_data = b'\\x50\\x51'
>>> escaped_data.decode("unicode_escape")

python / nodejsだと、どううやるんだっけ。。。

参考資料

https://stackoverflow.com/questions/10944907/python-unescape-xxx

php で JSONのエラーチェックをする,json_last_error

JSON が正しい形式かどうかチェックする

APIで受け取ったときに、リクエストパラメータの代わりに JSONを受け取るので、JSONの型式をチェックしないといけない。

こういうときに json_last_error() を使えばエラー内容がある程度は見れるようになっている。

<?php
    $ret = @json_decode($this->json);
    if (json_last_error() !== JSON_ERROR_NONE){
      return "JSONエラー:".$this->json;
    }
    return json_encode($ret, JSON_PRETTY_PRINT );

まぁみんなフレームワークでやってるんだろうけど、エラーの内容は知りたいよねやっぱり。

参考資料

http://jp2.php.net/manual/en/function.json-decode.php

Mac/iOSのSafariと macのキーチェンの共有その2

macicloudキーチェンが使われない問題について引き続き

前回

MacのicloudキーチェインとSafariのキーチェインは別物だった。 - それマグで!

Safariがキーチェンを使うタイミングで保存される。

Safariがキーチェンに保存されている「パスワード」にアクセス許可を求め、それを許可したタイミングで保存される。

f:id:takuya_1st:20180614184518p:plain:w250

このタイミングで、Safariがキーチェンに保存済みのパスワード使っていいですか?と聞いてくるので、ここで許可するとSafariのパスワード一覧にキーチェンのパスワードが出てくるようになる。さらに、許可した結果がiCloud同期されて、iOSのパスワード一覧に出てくるようになる。Macのキーチェンに該当のiCloudの項目が増える。キーチェンの管理画面で、ローカルからiCloudで手作業移しても駄目なようだ。なぜだ・・・

Safariがアクセス許可を求める前

f:id:takuya_1st:20180614184608p:plain:w250

Safariにアクセス許可を与えた後

f:id:takuya_1st:20180614184839p:plain:w250

Macのキーチェンで項目が変化する。

物によってはローカル→ iCloudへ移動する??

これが割と鬱陶しい。

ローカルのキーチェンはSafariで許可するとiCloudキーチェンへ移動している。アレコレ試したけど、移動してないものもある??よくわからない。。(これは追調査が必要だ。

今回わかった、ポイント

Safariで一度アクセス許可与えることが大事。まじかー

めんどくさい・・・

Macのキーチェンにあるicloudの項目を手作業で操作するのは、あまり関係ないですね。

まだわからないポイント

KeyChains が同期されるタイミングと、同期される条件。

macOSSafari がローカルキーチェンを使った後に、iOSに同期されるものと同期されないものがあるところ。

今回は、Safariのダイアログで一度許可することで「macOSiOS」でパスワードが同期されるものもある。ということがわかった。

キーチェン謎すぎる。

iOS12 で1Passwordがサポートされるなら、もうキーチェンすてて課金したほうが早いんじゃないかと思えてきた。

systemd-networkdが初期設定で有効にならないことがある。

systemd-networkd が enable になってない。

まいった。何度かこういう事態が発生する。

Linuxを再起動するとネットワークがつながらない。

DHCPで割当する、ネットワークが再起動後に有効にならない。VirtualBoxでよく起きる。

そのたびに ip set ...restart systemd-networkd していた。

初期インストールが原因かもしれない・

なぜ有効にならないのか解らない。が、VirtualBoxでネットワークをつけているが、Linuxのインストール時に、ネットワーク構成を自動設定したときもスキップしてたりでも起きてる。 また、ネットワークを追加したときにも起きる。

CentOSで試したら、スキップしたときにこの現象が起きてるっぽいし、Debianだと自動設定しても有効になってない。なんですかね。。。systemd 怖い。

対策は手作業で有効にする。

systemctl enable systemd-networkd

これで有効にすると設定が有効になるので、再起動後にもDHCPでネットワークがつながる。

うーん。。。なぞ

Systemd-networkdのDHCPネットワークの設定

systemd でのDHCPIPアドレスの割当をもらってくる

よくある例なので、ぱぱっと書いておく。

対象

systemd になってるLinuxディストーション。 今回は、 ubuntu / debian で設定をする。

準備するファイル

/etc/systemd/network にファイルを用意する。

/etc/systemd/network/dhcp.network

名前は何でもいい。

ファイルに記載する

[Match]
Name=en*

[Network]
DHCP=yes

DHCPをYESとかくCentっぽい。とにかくネットワークの設定はここ(/etc/systemd/network)にファイルを作って管理する。

固定IPのときは

[Match]
Name=en*

[Network]
Address=192.168.0.15/24
Gateway=192.168.0.1

などとすればOK

再起動する。

sudo systemctl restart systemd-networkd

わたしは、ここで restart networking.service をやってしまい、反映されないって10数分悩んだ。

ポイント

systemd-networkd で ネットワークを管理する。

/etc/networking/interfce の networking に依る管理 は systemd-networkd から起動する service になっている。

もちろん 旧来のディストーション依存のやり方でも構わない。ただそのときは sytemd と設定が違うのでググり方を間違えないこと。

2018-06-13 追記

うちの環境では、再起動してもネットワークがつながらないので、ずっと悩んでた。VirtualBoxのホストオンリーアダプタで頻発するから、ホストオンリーアダプタやブリッジネットワークのプロミスキャス・モードだと思ってたら、全然違った。

systemd に networkd が登録されてなかったので、手動登録した。

sudo systemctl enable  systemd-networkd

この減少はCentなどでも見られた。インストール時にNIC(ethernet)を自動設定にしてないときに、インストール後にネットワークカードを入れたら間違いなく起きるよね。はぁ。。。

enabled にしたあとのnetworkd の依存関係

takuya@debian01:~$ sudo systemctl list-dependencies  systemd-networkd
systemd-networkd.service
● ├─org.freedesktop.network1.busname
● ├─system.slice
● └─network.target

参考資料

Debian 資料 5.3. The modern network configuration without GUI

http://yukithm.blogspot.com/2014/05/systemd-networkd.html

マネックス証券のパスワードは8−10文字

IPOくじにチャレンジするためにマネックスの講座を復活させた。

口座を作ろうとしたら、すでに登録済みだった。休眠してた。

パスワードが10文字まで?

マネックス証券のアカウントを発掘したので、パスワード再発行させていただいた。

パスワードは8−10文字まで

最大文字数に制限があるのは、とても怖い。ハッシュ化せずに保存してるのではないだろうか。文字列長に制限があるというのは、DBのカラムのvarchar の制限を受けている可能性が考えられる。

f:id:takuya_1st:20180611191740p:plain

ログインIDは、顧客コード

顧客コードは公開情報なので、公開情報でログインIDの憶測が可能になるので嫌。

f:id:takuya_1st:20180611192707p:plain

うーん

あんまり近寄らんとこ。

input type=hidden の値が変わったら通知したい。

JSをデバッグしててhiddenがどこから更新されてるのか知りたかった。

ある操作をしたら、input[type=hidden] が書き換わるので、そのJSを特定しようと頑張ろうとした。

めっちゃめんどくさい。hidden には onchangeイベントが発火しないんですよ。

MutationObserverを使うとできるんです。

var observer = new MutationObserver(function (MutationRecords, MutationObserver) {
  debugger;
});

observer.observe(document.querySelector("input[type='hidden]"), {
  childList: false,
});

これで監視はできるんだけど、面倒なので input[type=hidden] を input[type=text]にして、display:none にしたほうが早い。そりゃそうだよね。ってすごく納得した。

参考資料

INPUT要素でtype属性がhiddenの要素のvalue値に変更があったらchangeイベントを発火させる - babu_babu_babooのごみ箱

printf で左寄せ

printfで文字列の左詰めをやる

意外に忘れているので、メモ

printf で文字列を右余白の左寄せをやろうとおもったらこれ

マイナスをつけたら左に寄ります。

%-5s

例 シェルでやるばあい

takuya@Desktop$ printf "%-5s\n" a ab abc
a
ab
abc

ruby でやるばあい

>> %w/a aaa aaaa/.each{|e|  printf "%-5s--\n", e  }
a    --
aaa  --
aaaa --

printf 便利ですねー