2018/04/05(木)09:11
bash script で CGI 作り - 指定時刻に Wake on LAN service
bash script で CGI を書いて指定時刻に Wake On LAN をする自宅内サービスを作っている。そういえば昔shellshockなんていう話も有った。一応サーバーの bash を確認して問題を起こさないことを確かめる。
働いていた時に bash で CGI を書いていると言ったら、「どうやって?」て言われたっけ?環境変数 QUERY_STRING から CGI 変数(正確な言い方はなんだっけ?)を取り出せる仕掛けを作れば、コマンドラインから起動するスクリプトと同じような感覚で書ける。次のコード片は CGI 変数を取り出す部分だ。書いた CGI より抜粋する。
(2018/4/5 追記 余計な key="$1" を削除)#!/bin/bash -f# wakeup host at specified time.# CGI vars:# hostname=HostName# wake_second=UnixTimeSecond# wake_time=HumanReadableDateTimefunction uri_unescape() { local b c i l b="" while read do i=0 l=${#REPLY} while (( ${i} < ${l} )) do c=${REPLY:${i}:1} case ${#b} in (0) case "${c}" in (+) echo -n " " ;; (%) b='\x' ;; (*) echo -n "${c}" ;; esac ;; (2) b="${b}${c}" ;; (3) b="${b}${c}" printf "%b" "${b}" b="" ;; (*) echo -n "${c}" b="" ;; esac i=$(( ${i} + 1 )) done done}function query_var() { echo ${QUERY_STRING} | \ tr '&' '\n' | \ grep "^$1=" | \ sed -n -e "s/^$1=//p" | \ uri_unescape}shell_operators='$|&;<>(){}[]`'wake_host=`query_var hostname | tr -dc '[:alnum:]._-' `wake_second=`query_var wake_second | tr -dc '+-[:digit:]'`wake_time=`query_var wake_time | tr -d "${shell_operators}"`あまり込み入ったトリックは使わず、平凡に書いた。uri_unescape が % や + で escape された文字を decode する処理、query_var が CGI 変数名を指定して、値を取り出す処理になる。perl を使えば簡単では?... まあそうなんだ。
大よそ動いている指定時刻に Wake On LAN する CGI scriptはまだ改良の余地がある。マシンが稼働していなくても動くように hostname → MAC address の辞書を持たせる。form を付けるcancel 機能を付ける。DoS に耐性を持たせる。仮稼働中をさせて実用に支障が無いか見つつ改良方針を考えないと。
本当は RTC の wake 機能を使えば十分なはず。Windows ならタスクスケジューラーだし、Linux なら /sys/class/rtc/rtc0/wakealarm だ。たまに不発になるときの bad knowhow 的な CGI なんだよな...