日報 #55 - シェルの訓練として
おいおい!
今日も何もしてねぇぞ!!
チケット作りっぱなしでバックレか平山!
元気でやってます。
ところで、かなり的外れな話ですがbasic認証にexpireを付けたくなるシーンに出くわしました。
まぁなんだっていいんですが、すごい簡単に期限付きのID/PASSを発行したいってことです。
もちろんBASIC認証にそんな機能ない、というかそもそもそういうものじゃないので無理やりやります。
DB上にname,pass,exipreを保存して、それをcronで毎日確認。
そのDB情報に沿ってhtpasswdファイルを作成する、ってことさえ出来れば良さそうです。
一見すると簡単ですし、phpとか使えばすぐ出来そうですね。
もちろんそんなことガン無視してbashでやりましょう!
結論から言うとMySQLとシェルを連携させるのが中々難しいです。
問題は「MySQLからの出力をどうパースするか」これに尽きます。
ですが、1つずつやっていくとシンプルです。
まず一行ずつ配列とします。これはIFS=$'\n'と変更して()で取得。
次にkey-valueの構造で持たなければならないのが厄介です。
ここでSELECT文に工夫を凝らします。
後にeval関数でID名を変数名として、${ID名}=${VALUE値}のように突っ込無事を考えて、
CONCATでもってCONCAT('name=', name),CONCAT('pass=', pass)こんな感じに出力しておく。
あとはevalして変数名と値を取得する。
これでnameとpassが手に入りますね。
結果こんな感じです。
#! /bin/bash FILE_NAME=.htpasswd DEF_ID=hoge_master DEF_PASS=hoge_pass # init htpasswd htpasswd -cb ${FILE_NAME} ${DEF_ID} ${DEF_PASS} 1>/dev/null 2>&1 # get user-pass list from db EXPIRE_DATE=`date +"%Y-%m-%d %H:%M:%S"` MYSQL_USER=hoge_user MYSQL_PASS=hoge_pass MYSQL_HOST=hoge_host MYSQL_DB=hoge_db MYSQL_QUERY=`echo "SELECT CONCAT('name=', name),CONCAT('pass=', pass) FROM basic_auth WHERE expire >= '${EXPIRE_DATE}'"` # ID/PASS from DB IFS=$'\n' RST=(`mysql -u ${MYSQL_USER} -p${MYSQL_PASS} -h ${MYSQL_HOST} ${MYSQL_DB} -e "${MYSQL_QUERY}"`) # Get variables by "eval ${ID}=${VALUE}" ITE=0 for RES in ${RST[@]} do if [ "$ITE" -gt 0 ] ; then eval `echo $RES` echo "$ITE - ${name}" echo "$ITE - ${pass}" htpasswd -nb ${name} ${pass} 1>>${FILE_NAME} fi ITE=`expr $ITE + 1` done
これをcronで食わせれば指定場所に.htpasswdが作成されます。
擬似的にexpireがかかっているように見えますね。
シェルに不慣れなので、こういうのが訓練になります。
楽しいね。じゃぁね。