それマグで!

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

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

nginx で特定の拡張子をphpで処理する(SetHandler代替)

特定の拡張子をphpなどで処理する

css や js だけじゃなく 画像などをphpで処理したい。Apacheだと addhandler / sethandler で出来るアレ。nginx でもやろうかなと。

画像のリクエストログやリサイズをWebサーバーでやってるとかったるいので、phpで処理してキャッシュ制御すれば楽だよね。セッションチェックとかさ。

nginx での設定例

拡張子php と zip を php-fpmに飛ばしている例。

    location ~ \.(php|zip)$ {
      include fastcgi_params;
      fastcgi_param PATH_INFO $fastcgi_path_info;
      fastcgi_param SCRIPT_FILENAME /var/www/example.com/public/info.php$fastcgi_script_name;
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_pass unix:/path/to/php-fpm.sock;
    }

ポイント

SCRIPT_FILENAME の指定 。

php の場合は SCRIPT_FILENAME を使ってPATHINFOで実行するファイルを指定することが出来て、これをphp-fpm経由にしてあげれば、任意のファイルを好きなファイルで処理できる。便利。

PATHINFOで取得した場合

$_SERVER['ORIG_SCRIPT_FILENAME']
$_SERVER['ORIG_SCRIPT_NAME']

リクエストされたファイル名

$_SERVER['PATH_TRANSLATED']

php-fpm で php.iniの設定渡す/display_errorsなどをPHP_VALUEで設定する。

PHP_FLAGを使いたい。

apache の mod_phpapachefcgiなら簡単にできるんだけど、nginxだとfcgiでどうやって 初期設定を渡したら良いんだろうか。

こうすれば出来る。

fastcgi_param PHP_FLAG "display_errors=on \n display_startup_errors=on";
fastcgi_param PHP_VALUE "error_reporting=-1";

php をfpm で設定するときに、在るサイトだけ display_errors をオンにしたいとか在るんですよ。

日本語でググっても php-fpm.ini のグローバル設定を変えろ的な記事しかなかったので、アレコレ調べた。

サイトごとにエラー設定を変える。

トラブルが出ているサイトを一時的にdisplay_errors して見てみるとか。

デプロイ時だけエラーになってなんだコレ??ってphpのエラーを追いかけるときかに便利。

サイトごとのエラーログが便利。

fastcgi_param PHP_VALUE  "error_log=/var/log/nginx/my-site.error.log"

複数書きたいときは改行

改行で書くのが楽でいいよ。スペース区切りはダメ。

    fastcgi_param   PHP_VALUE "
        display_errors=on
        display_startup_errors=on
        error_reporting=E_ALL
        error_log=/var/log/nginx/comic-viewer.error.log";

または Name=Value\nName=Value にする.

だめな例

  fastcgi_param   PHP_VALUE "display_errors=on";
  fastcgi_param   PHP_VALUE "display_startup_errors=on";

PHP_VALUE は1つしか取ってくれない。 (そのうちに、nginxやphp-fpmのバージョンアップで解決するんじゃないかな。

ただし再起動が必要

 sudo systemctl restart  nginx php7.0-fpm

fpm の再起動をすると設定が反映される。再起動をしなくてもキャッシュが消えたら反映されると思うけど、php-fpmのキャッシュ機構は多分複雑だろうから追いかけ用途思っても時間が足りなくて出来てない。

前の記事

nginx + php-fpm で display_startup_erros=on にしてシンタックスエラーを表示する。 - それマグで!

PHP

phpで別アプリへのセッション受け渡し

php から別のアプリへセッションを受け渡したい

認証済みのセッションキーを、別のアプリへ受け渡ししたい。今回は mp4 と vlc でテストした。

渡す時

<?php
$url = 'http://example.com/sample.mp4';
$uri = "${uri}&PHPSESSID=".session_id();
$url = 'vlc-x-callback://x-callback-url/stream?url=$url'
header("Location: {$uri}");

受け取る時

ini_set("session.use_trans_sid",true;)
session_start();

フレームワークのサポートも、GET引数のチェックも何も要らない。便利。

引数の名前

デフォルトは "PHPSESSID" なので、ソレを入れても良い。 厳密にやるなら session_name()を使う。

$uri = "${uri}&".session_name()."=".session_id();
$uri = "${uri}&sid=".session_id();

サンプル

<?php

// これだけ
ini_set("session.use_trans_sid",true);
ini_set('session.use_only_cookies', 'off');
session_start();

if ( !empty($_SESSION['is_login']) && $_SESSION['is_login'] ) {
  echo "OK";
  http_response_code(200);
  return ;
}else{
  echo "OK";
  http_response_code(401);
  return ;
}

参考資料

http://php.net/manual/en/session.idpassing.php

セッション

ハンマーセッション!(7) (週刊少年マガジンコミックス)

ハンマーセッション!(7) (週刊少年マガジンコミックス)

ls コマンドで結果を1行ごと1列にならべてループを楽にしたい

ls の結果からディレクトリ名を除きたい。

ls すると結果がズラッと並んでしまって、後処理をしにくい

takuya@Desktop$ ls /
'['     cat     cp    date   df           echo   expr       kill   launchctl   ln   mkdir   pax   pwd   rm      sh      stty   tcsh   unlink      zsh
 bash   chmod   csh   dd     domainname   ed     hostname   ksh    link        ls   mv      ps    rcp   rmdir   sleep   sync   test   wait4path

1行に並べたい

なんと、手軽に1行に並べることが出来ます!single-column -1 オプションです。

takuya@Desktop$ ls -1 /bin
'['
bash
cat
chmod
cp
csh
date
dd
df
domainname
echo
ed
expr
hostname

man からの抜粋

え?カンマ区切りとかできるんだけどwww

      --format=WORD
              across -x, commas -m, horizontal -x, long -l, single-column -1, verbose -l, vertical -C

-1 (one) と -l (エル) は似てる上に同じカテゴリの仲間だったなんて驚き!

ループで回すならIFSで済むんだ。

IFSで済むんだけど、ruby IO.readlineやExcel など、ファイル読み込み系のプログラムから読み込むときは、開業が楽だよねやっぱり。

関連する記事

IFS 関連の記事

参考資料

ls -d 関連商品

L.S.D(1) (NINO)

L.S.D(1) (NINO)

NginxでContent-Typeを指定する。

nginx で Content-Typeを指定する。

すぐに皆が思いつきそうな設定例はこれ。わりと何処にでも書いてある。だけど、、、本当にコレがベターなの?

      location ~ \.mkv$  {
       default_type video/mp4;
      }

types がある。

マニュアル読んでると types がった。

types {
  video/mp4 mkv;
}

types は server や location コンテキスト内部にも記述ができる。

server {
  location ~ / {
    types {
      video/mp4 mkv;
    }
  }
}

ちなみに、if の中で default_type は出来ないので、if 文は使えない。

nginx って if 文で一見すると読みやすそうだけど、設定していくと if 文は悪 if is Evil とか書いてる文書にぶち当たるし、 if の中で出来ることは限られる。

nginx って意外と使いにくい。

参考資料

http://nginx.org/en/docs/http/ngx_http_core_module.html#types

find コマンドでgit フォルダを無視したい(ただし.gitフォルダは表示したい

find コマンドで gitがズラッと並ぶの不便

ああ、、、、要らないよこんなの。。。

takuya@pages$ find
takuya@pages-sample$ $(which find ) -type f
./.git/COMMIT_EDITMSG
./.git/config
./.git/description
./.git/FETCH_HEAD
./.git/HEAD
./.git/index
./.git/info/exclude
./.git/logs/HEAD
./.git/logs/refs/heads/master
./.git/logs/refs/remotes/origin/master
./.git/objects/02/399e371c5d109e1c8221c74c9135a0c069d8fb
./.git/objects/07/968b16567a3c9b2eae0a3749eeb4f16d90d16c
./.git/objects/0d/e9c93edbe76efb6f0deedb1078746667460c0e
./.git/objects/0e/5e7135586f82d8b80f243e18c57443fca70b00

not マッチを使う。

find -mindepth 1 -not -iwholename *.git/*

not マッチをして .git を無視した例

takuya@pages-sample$ find
/Users/takuya/.bin/find -mindepth 1 -not -iwholename *.git/*
./.git
./.gitignore
./.gitlab-ci.yml
./public
./public/index.html
./README.md

object は要らないけど、hookやconfigは見たいんだ。

find の -not は重ねて書くと、or 条件で積み重ねてていく。 というか、マッチしたものを除外するので正確には、-not 条件を 足す感じ

find -mindepth 1  \
-not -iwholename *.git/objects* \
-not -iwholename *.git/logs* \
-not -iwholename *.git/refs* \
-not -iwholename *.git/*HEAD* \
-not -iwholename *.git/in*

適度に選ぶ。

ガッツリ.git 消しちゃうのも不便。

.gitignroe.git/config とか .gitlatb-ci.yml とかもあるので適度に必要なものだけを残して、見ても仕方ないものを消せる。

find に ignroe scm っていうオプションがアレばいいのにね。

関連記事

git 萌え本

わかばちゃんと学ぶ Git使い方入門〈GitHub、Bitbucket、SourceTree〉

わかばちゃんと学ぶ Git使い方入門〈GitHub、Bitbucket、SourceTree〉

vimでphp.iniの設定ファイルを開くときのハイライトさせるファイルタイプ設定

vim で iniファイルのハイライト

ini ファイルは dosini という名前でデフォルト登録されている。

:set ft=dosini

モードラインを書いておく。

ファイルの1行目に書いておけば、モードラインとして設定を拾ってくれるので多少ファイルの中身とファイルの拡張子が合わないときでも便利。

 # vim: ft=dosini ts=2 sw=2 sts=2 sr noet:

こうしておけば、php-fpm.conf とか iniのくせに conf 拡張子になってるものにも対応できる

ちなみに、php.iniの場合は コメントアウトの文字が # じゃなくて ; なので注意

; vim: ft=dosini ts=2 sw=2 sts=2 sr noet:

設定例

f:id:takuya_1st:20180225030816p:plain

関連資料

vim のモードラインでvim設定(タブなど)をファイルに書く - それマグで!

参考資料

http://www.gregfreeman.io/2011/vim-syntax-highlighting-for-php-fpm-conf-files/

2018年8月21日追記

末尾に、 「:」が抜けていたので修正。

vim スタイル

ln -s で相対シンボリック作成のやりかたと解説。

ln -s で失敗した経験ありますよね?

/var/www/log/index.php から /var/www/html/index.php へリンクする場合。こういうときに、相対パスをぱぱっと作れたら嬉しいでしょ?

でも、ぱぱっと作れなかったり、相対パスを作ったつもりがリンク切れてたり。。そして、失敗を繰り返してしまう。

最後には、諦めてフルパスでリンク書いてたり。しませんか?

ところが、フルパスだとバックアップフォルダ移動後にリンクが壊れたりする。

相対パスでリンクすると、あとで楽だもんね。

だから基本的に相対パスで書きたいよね?うん。だよね???だよね???

というわけで、相対パスシンボリックリンクの作り方。

お急ぎの人は

記事の最後へどうぞ。

次のようなリンクを作ってみます。

ファイルをリンクする場合に相対パス絶対パスで作ってみます。

絶対パスなら次のように

ln -s /var/www/log/index.php  /var/www/html/index.php

相対パスなら次のように・・・?

ln -s ./index.php  /var/www/html/index.php

ん?相対パスのスタートはどこだ?誰から見た相対パスを入れるんだ?

相対パスは、宛先ファイルから見た相対です。

/var/www/log/index.php から /var/www/html/index.php へリンクする場合。

つまり宛先からみた、相対パスをいれる。

ln -s ../log/index.php  /var/www/html/index.php

相対パスの求め方。

作りたいリンクから見た相対パスを1番目に指定する。

ln -s は2番目の引数を考えてから、1番目の引数を考える。 ところが一般的なコマンドは目的地(2番目)のコマンドの内容を考える。なので、思考のパターンが逆になる。

このへんがいつもわかりにくいミスする原因なんだと思う。

カレントディレクトリ。

ln で作成するリンクのファイルからみて相対パスにカレントディレクトリは考えない。

作成するリンクと、作業中のカレントディレクト

作成するリンクファイルはワーキングディレクトリからの相対パスで指定することが出来る。

cd /var/www/
ln -s ../log/index.php  ./html/index.php

ここで、 次に注意する。

  • ../log/index.php作成するリンクから見た 相対パス
  • ./html/index.php作業ディレクトリからみた 相対パス

引数それぞれで、相対パスの元が異なるの。ここがよくミスしたり誤解が増えるポイントだと思うんですよね。

ポイントのおさらい

  • 第1引数  作成ファイルから見た 相対パス
  • 第2引数 ワーキングディレクトリからみた 相対パス

相対パスの求め方

たとえば realpath を使ってみる。

$ realpath --relative-to=$( dirname /var/www/html/index.php)  /var/www/log/index.php
../log/index.php
$ ln -s ../log/index.php  /var/www/html/index.php

コレらを併せて。

ln -s $(realpath --relative-to=$( dirname /var/www/html/index.php)  /var/www/log/index.php)  /var/www/html/index.php

面倒くさい。

realpath と ln -s を組み合わせるのは本当に面倒くさい

-r オプション最強

この目的のためにあるのが、r オプション

ln -sr で解決

相対パスを自動て解決してくれるのが -r オプション。まじでコレ付けるだけで解決する魔法のオプション

ln -s -r /var/www/log/index.php /var/www/index.php

r 付けるだけ これで今の理屈を全部やってくれる。知らなかったら絶対に損するオプション。

どこで活躍する?

バージョンごとにフォルダ変えたり、dockerfile とか

sites-enablesites-available など 設定ファイルの有効・無効をリンクで切り替える構成にするときにすごく重宝する。

-r オプションが無いんだけど怒!!

そういうときは、困りますよね。 ワーキング・フォルダを移動します。 リンクを作成するフォルダに cd してから相対パスで指定するとうまくいきます。

cd /var/www/html  ## リンク作成するディレクトリへ先にcd します。
ln -s ../log/index.html ./index.html

ディレクトリのリンクの場合も同じです。

関連資料

bashでファイルパスの相対パスを得る(絶対パスの取得やパスの正規化も)/realpath利用 - それマグで!

参考資料

man ln

関連アイテム

ファミコンミニ リンクの冒険

ファミコンミニ リンクの冒険

f:id:takuya_1st:20180225020756p:plain:w200

Systemd 時代のresolv.conf

/etc/resolv.confがない。

驚いた、Resove.conf がなくなってるんですよ

systemd 管理下に置かれた

/etc/systemd/resolved.conf

代わりに、次のファイルがが出来た

昔からある resolv.conf は systemd が管理してしまう。

もしかしてリンク?

takuya@ubuntu01:~$ ll /etc/resolv.conf
lrwxrwxrwx 1 root root 39 11月  8 22:56 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

なんてことだ。。。。なんて面倒くさいことをやってくれるんだ。。。

リロードが必要

DNSなど名前解決設定を更新したら、sysd でリロードが必要だった。

systemctl restart systemd-resolved.service

ナゼこんなことになってるのか。

resolv.conf は systemd の unit になった。 ネットワーク設定に従ってDHCPで書き換えることが多くて、ネットワークのターゲットに従う。

個人的には、ネームサーバーなんて固定で良いんだけどなぁ。

ruby のDateTimeを30分(1800)すすめる

ruby のDateTimeの時刻をすすめる

datetime + 1800/(24*60*60).to_f

ただ時間をすすめるだけだと、単純にInt秒数を足すことが最短経路だった。

いちいち AcrtiveSupport 的なものに頼るのも面倒な話だ。だけどもう少し楽にならないのかな。

ad

MouseEvent Path が便利

とりあえずマウスイベントをデバッグしたり調べたいとき

document.body.addEventListener('click',function(e){ debugger ; })

e.path クリックした要素から、body での各パスが入ってる。 バブリングを順番に辿れるので便利。

path を見れば途中の経路になにがあるのかよく分かる。

path
eventPhase
isTrusted
bubble

ただし、イベントリスナーを管理するのはめんどくさいだろうな。

エレメントにハンドラつけてたら、エレメントをコピーしたらハンドラを一掃できて便利だしな。

複数Gmailを手軽に管理する方法。スマホ設定も通知も迷惑メール対策がぐっと楽になるテクニック

Gmailのアカウントが増えすぎて困る

Gmailのアカウントが増えすぎ。

常時に大量にメールチェックするのがもう無理。っていうかメールは通知以外で殆ど使わないと思うんだ。

そうだフォワードしよう

メールは転送してフォワードしてしまえば良いのではないか。

メインのメアドに全部転送することにした。

メインのメアドはGSuite(Google Apps)を開始当初から使ってるので10年くらい。そこに全部持ってくることにした。

f:id:takuya_1st:20180222031206p:plain

転送設定

Googleアカウントには、転送を設定する。

f:id:takuya_1st:20180222003058p:plain

返信どうするの?→1箇所で全部返信できるよ

メインのメアドから返信出来ます。Gmailどうしで転送設定するとGmailではFromもそのまま使えるようになってて、超便利!

スパムフィルタがあって便利

GMailから転送するとスパムフィルタのフィルタ結果のメールしか転送されない。

つまり、古くからの単純転送とは違ってフィルタ済みのメールが転送される。

そのためずっと転送されるメールが少ない。

だから、メインのメアドのメールボックスが爆発する心配もあまりない。

f:id:takuya_1st:20180222031737p:plain

iPhone / iPad ( iOS ) の設定が楽

スマートフォンにメールボックスの設定や、通知設定をするとき、1つのアカウントだけを設定するので楽。複数アカウントを設定するのは機種変更時や端末追加でたくさん登録が必要になって面倒くさい。

f:id:takuya_1st:20180222031928p:plain

結論

Gmail複数アカウントを束ねるメアドを決めて使う。

転送だけじゃなく、「権限の移譲」ということで複数人でアカウント権限をシェアして使うことも出来る。

問い合わせメールや返信メールは権限の移譲で、自分のメアドなら転送設定が楽。

これでGmailのメアドを無限に増やせるんだけど、そのうち制限が掛かりそうなのでいまのうちにたくさんメアドとっておくほうが良いかもね。

参考資料

権限移譲

転送設定

Hacking Gmail (English Edition)

Hacking Gmail (English Edition)

bashの補完のcompgenでハイフン(ダッシュ/-)の引数を補完する

問題点

-list から -listDevice のようなcompletion が出来なくて、invalid option なっちゃう。

$ networksetup -list<TAB>
compgen 無効な引数です

キーワードの補完ができない。

ハイフンを付けた引数を補完するときは

compgen にハイフンをハイフン( -- )で渡してあげる。

compgen -W $list -- ${COMP_WORDS[COMP_CWORD]

-list -listdevice などのハイフンが入ったオプションを補完しようとすると、無効なオプション として compgen がwordとして compgen自身へのオプションとして持っていっちゃう

つまり

compgen -W ワードリスト -- '-list'

のようにしてあげないと、 -list から -listDevice のようなcompletion が出来なくて、invalid option なっちゃう。

compgen の使い方

compgen の使い方を見ておくと、次のようになっている。

compgen: compgen [-abcdefgjksuv] [-o option]
 [-A action] [-G globpat] [-W wordlist]  [-F function] 
[-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
    オプションに基づいた補完候補を表示します。

    シェル関数の中で補完候補を生成するために使用するように意図されています。
    オプション引数 WORD が与えられた場合、WORD に対して一致した候補が生成
    されます。

    終了ステータス:
    無効なオプションが与えられるかエラーが発生しない限り成功を返します

サンプル

-listXXXX が大量にあるコマンド補完する例です。

#!/usr/bin/env bash 

### 補完関数。
_takuya_networksetup (){
  curr="${COMP_WORDS[@]}"
  prev="${COMP_WORDS[$COMP_CWORD-1]}"
  cmd_name=networksetup

  if [[  $prev =~ $cmd_name ]] ; then 
      sub_command_list=$( networksetup -h | /usr/bin/grep networksetup | awk '{print $2}' )
      COMPREPLY=( $(compgen -W "$sub_command_list" -- ${COMP_WORDS[COMP_CWORD]}  ) ) 
    fi
}
complete -F _takuya_networksetup networksetup

参考商品

アタック Dash Button

アタック Dash Button

mysqldumpがなんかメッセージ吐くので、アップグレード

mysql の自動バックアップがWarnings

なんかエラー吐くので、しらべたら、MySQLMariaDB でしかもバージョンアップが終わってるのにテーブルが古いってことらしい

mysqldump: Couldn't execute 'show events': Cannot proceed because system tables used by Event Scheduler were found damaged at server start (1577)
mysqldump: Couldn't execute 'show events': Cannot proceed because system tables used by Event Scheduler were found damaged at server start (1577)

アップグレードコマンドを叩いてみた

root@acid: # mysqlcheck --no-defaults --check-upgrade --all-databases  --auto-repair -p 
Enter password:

そのご、アップグレードする。

root@acid:~# mysql_upgrade -p
Enter password:
MySQL upgrade detected
Phase 1/7: Checking and upgrading mysql database
Processing databases
mysql
mysql.column_stats                                 OK
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.event                                        OK
mysql.func                                         OK
mysql.gtid_slave_pos                               OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.host                                         OK
mysql.index_stats                                  OK
mysql.innodb_index_stats                           OK
mysql.innodb_table_stats                           OK
mysql.ndb_binlog_index                             OK
mysql.plugin                                       OK
mysql.proc                                         OK
mysql.procs_priv                                   OK
mysql.proxies_priv                                 OK
mysql.roles_mapping                                OK
mysql.servers                                      OK
mysql.table_stats                                  OK
mysql.tables_priv                                  OK
mysql.time_zone                                    OK
mysql.time_zone_leap_second                        OK
mysql.time_zone_name                               OK
mysql.time_zone_transition                         OK
mysql.time_zone_transition_type                    OK
mysql.user                                         OK
Phase 2/7: Installing used storage engines
Checking for tables with unknown storage engine
Phase 3/7: Fixing views from mysql
Phase 4/7: Running 'mysql_fix_privilege_tables'
Phase 5/7: Fixing table and database names
Phase 6/7: Checking and upgrading tables
Processing databases
epgrec
epgrec.rc_reserveTbl                               OK
(略 : データベースのテーブルを全部チェック
information_schema
performance_schema
wp_black
wp_black.wp1_commentmeta                           OK
(略 : データベースのテーブルを全部チェック
Phase 7/7: Running 'FLUSH PRIVILEGES'
OK
root@acid:~#

複数回の実行からは保護されてるっぽい

root@acid:~# mysql_upgrade -p
Enter password:
This installation of MySQL is already upgraded to 10.1.26-MariaDB, use --force if you still need to run mysql_upgrade
root@acid:~#

参考資料

https://dev.mysql.com/doc/refman/5.5/en/mysql-upgrade.html

https://mariadb.com/kb/en/library/mariadb-community-couldnt-execute-show-events-cannot-proceed-because-system/

今使ってるのMariaDBなのかMySQL(GPL)なのか、バージョンアップする前に調べたい。

apt で入れるのか、なにで入れてるのかわからなくなる。

docker のイメージだとか、mysql を含んだdeb とかあるから、ちゃんと確認した方がいいよね。

mysql takuya@localhost:(none)> select VERSION();
+--------------------------+
| VERSION()                |
|--------------------------|
| 10.1.26-MariaDB-0+deb9u1 |
+--------------------------+
1 row in set

参考資料

https://mariadb.com/kb/en/library/version/

マリアバージョン