2019/04/18

CentOS 7 のコンソール画面でキーマップを変更する

キーボードのキーが押下されるとキーコードと呼ばれる一意の値がシステムに通知される。
キーマップはこのキーコードに対して文字を定義するためのファイルで、 システム標準のキーマップは /lib/kbd/keymaps/legacy/i386/qwerty に格納されている。
CentOS 7 のコンソール画面のキーマップ情報は /etc/vconsole.conf ファイルに格納されていて、 起動時に自動で読み込まれコンソール画面のキーマップが設定される。

$ cat /etc/vconsole.con
KEYMAP="us"
FONT="latarcyrheb-sun16"
    

例えば US 配列のキーボードで邪魔な Caps Lock を Control に変更したい場合は Caps Lock のキーコードを調べて押下された時に Control が入力される様なキーマップを用意すれば良い。
キーマップは showkey コマンドで調査する事ができる。
showkey コマンドは画面に表示されている通り最後の入力の10秒後に終了する。

$ showkey
kb mode was UNICODE
[if you are trying this under X, it might not work
since the X server is also reading /dev/console ]

press any key (program terminates 10s acter last keypress)...
keycode 58 press                      ここで Capl Lock キーを押下
keycode 58 release                    ここで Capl Lock キーを離す
$
    
結果から Caps Lock キーのキーコードは 58 なのでキーコード 58 に対して Control を入力するキーマップを作成する。 キーマップファイルは他のキーマップファイルを読み込む事ができるので、オリジナルの us.map を読み込んで Caps Lock だけを変更する。 この時、Shift + Caps Lock の場合は Caps Lock としてみる。
キーマップファイルは gzip 形式で圧縮する必要があるので圧縮し、所定のディレクトリに格納する。
# cat << EOF | gzip -c > /lib/kbd/keymaps/legacy/i386/qwerty/us-nocaps.map.gz
include "us.map"

keycode 58 = Control
    shift keycode 58 = Caps_Lock
EOF
    

キーマップファイルの準備ができたら loadkeys コマンドでキーマップを読み込み挙動を確認する。

# loadkeys /lib/kbd/keymaps/legacy/i386/qwerty/us-nocaps.map.gz
Loading /lib/kbd/keymaps/legacy/i386/qwerty/us-nocaps.map.gz
    
Caps Lock キーが Control に、Shift + Caps Lock キーが Caps Lock になる事が確認できたら、 起動時にキーマップが読み込まれる様に /etc/vconsole.conf ファイルを編集する。
# cp /etc/vconsole.conf /etc/vconsole.conf.orig
# sed '/KEYMAP/ s/us/us-nocaps/' /etc/vconsole.conf.orig > /etc/vconsole.conf
    
これで再起動しても Caps Lock は Control となる。

2019/02/15

時間の範囲を指定してログを抽出する

syslog や apache のログファイルなどから時間の範囲を指定してログを抽出したい場合、 ログファイルの時間表記をそのまま比較するのは面倒なので一度 epoch に置き換えて比較すると楽だ。

現在時刻から epoch は date (1) のフォーマット指定 '+%s' を利用する事で取得できるが、 指定した時刻から epoch を取得する汎用的な手法は現状では存在しないので今回は GNU date の '-d' オプションを利用する。

例として combined 形式の apache のログの時間範囲を抽出してみる。
combined 形式の apache のログは以下のフォーマットとなっているので、時刻は空白区切りの4番目のフィールドに格納されている。 そこで、ログの行毎に4番目フィールドの時刻を epoch に変換して比較する事で指定された時間内のログを抽出できる。

192.168.15.134 - - [14/Feb/2019:03:35:54 +0900] "GET / HTTP/1.1" 200 1920 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
192.168.99.23 - - [14/Feb/2019:07:20:35 +0900] "GET / HTTP/1.1" 200 1920 "https://www.bsdhack.org/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36; 360Spider"
192.168.157.241 - - [14/Feb/2019:09:28:45 +0900] "GET / HTTP/1.1" 200 1920 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
192.168.15.143 - - [14/Feb/2019:09:58:44 +0900] "GET /bsdhack.css HTTP/1.1" 200 3246 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
192.168.93.5 - - [14/Feb/2019:12:03:47 +0900] "GET / HTTP/1.1" 200 1920 "-" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1"
    

ただし、標準的な apache のログに格納されている時刻情報はそのままでは date (1) の '-d' オプションでは変換できない。

$ date -d "14/Feb/2019:09:28:45"
date: invalid date `14/Feb/2019:09:28:45'
    
そこで、 まずは date (1) で変換できる様な形式に変換してから変換する。 そのためには日付けの区切り文字 '/' と、日付け部と時間部を分割している ':' をスペースに置換すれば良い。
$ date -d "14 Feb 2019 09:28:45"
Thu Feb 14 09:28:45 JST 2019
    
全体の流れとしてはログファイルから1行ずつ読み込み、時刻フィールドを epoch に変換して基準時刻と比較する処理を行う。 今回は全ての処理を awk (1) を利用して実装してみる。

  1#!/bin/sh
  2#   $1: 開始時間 -- date(1) が認識できる形式
  3#   $2: 終了時間 -- date(1) が認識できる形式
  4#   $3: ログファイル
  5
  6# 開始時間
  7start=$(date '+%s' -d "${1}")
  8# 終了時間
  9end=$(date '+%s' -d "${2}")
 10# ログ抽出
 11awk -v "start=${start}" -v "end=${end}" '{
 12    # 時刻フィールドを date(1) が認識できる形式に変換
 13    gsub(/[][/]/, " ", $4)
 14    sub(/:/, " ", $4)
 15    # ログの各行について時刻を epoch に変換する
 16    # $4 にはスペースが含まれているので全体をクォートする
 17    cmd = sprintf("date +%%s -d '"'%s'"'", $4);
 18    # date(1) を実行して epoch を変数 s に取得
 19    cmd | getline s;
 20    # コマンド実行でオープンされたディスクリプタをクローズ
 21    close(cmd);
 22    # 行が範囲内なら出力する
 23    if(start <= s && end >= s)
 24        print $0
 25}' ${3}
    

これで開始時間から終了時間の間のログを抽出できる。
行毎に時間の変換処理を実行するので実行に時間はかかってしまうのが現状の問題点。

2019/01/31

とあるサイトが変更になった時になるべく確実に変更通知を受け取りたい

なるべく確実に変更通知を受け取るためには、普段携行している iPhone への通知が一番良さそうに思う。
iPhone への通知で一番最初に思い浮かぶのは PUSH通知 (APNS) なのだが、 APNS を利用するためには Apple への Developer 登録などが必要で、そう簡単に送る事ができないと思う (Developer 登録などが不要で簡単に PUSH 通知を送る方法があれば是非教えて下さい)。

そこで iPhone で受信しているアドレスにメールを送信し、 更に普段からチェックしている slack で自分宛にダイレクトメッセージを送信する事にした。
iPhone の設定によりメールを受信した時や slack でダイレクトメッセージが投稿された時の通知を有効にする事で、 変更通知がなるべく確実に受け取れる事になると思う。

そのために以下のスクリプトを Linux などが稼働しているサーバ設置して cron などにより自動実行する。

  1#!/bin/sh
  2
  3# site
  4url="https://www.example.com"
  5old=${HOME}/.old.html
  6new=${HOME}/.new.html
  7# for mail
  8addr="mail@exapmle.net"
  9subject="[SITE CHANGEED]"
 10body="SITE CHANGED: ${url}" 
 11# for slack
 12slack="https://hooks.slack.com/services/XXXXXXXXX/YYYYYYYYY/ZZZZZZZZZZZZZZZZZZZZZZZZ"
 13name="name"                 # post name
 14channel="#channel"          # post channel
 15
 16curl -s ${url} > ${new}
 17test -f ${old} &&  
 18cmp -s ${old} ${new} || echo "${body}" | mail -s "${subject}" ${addr} &&
 19curl -sLX POST --data-urlencode "payload={\"channel\": \"${channel}\", \"username\": \"${name}\", \"text\": \"${body}\"}" ${slack}
 20
 21mv $new $old
    
slack でチャンネルではなくダイレクトメッセージを送信する場合は channel の値を適切に変更する。
web を検索すると `channel: @名前` とすれば良いとの記事を多く見かけるが、少なくとも最近の slack ではエラーとなってしまう。
その場合、slack の web 画面の左側に表示されている `ダイレクトメッセージ` をクリックした時に遷移するページの URL の最後の部分 (https://XXX.slack.com/messages/YYYYY/YYYYY の部分) を指定するとダイレクトメッセージが送信できる。

2019/01/02

本年度初キャンプ

本年度の初キャンプとして我が家では定番となった有野実苑に行って来ました。

Image: 20190102_035637276_iOS.jpg

安定の有野実苑

今回は…なんと!薪ストーブのお披露目となりました。

冬の時期に有野実苑に来る度に薪ストーブをレンタルして温まっていたのですが、 ついに自前の薪ストーブをゲットしてしまいました。
購入するにあたって機種などを色々と調べて悩んだのですが、 手入れの簡単なステンレス製で安心の日本製という事で、 tent-mark DESIGNS のウッドストーブを選びました。 純正オプションのウォータータンクがとても便利で、 いつでもお湯が使えるのは特に冬の時期には素晴らしいです。

Image: 20190102_053327151_iOS.jpg

tent-mark DESIGNS の薪ストーブ

Coleman の T.P.Crest の前室部分にセンゴクアラジンのカセットガスストーブを設置して、 クッションマットを敷いて電気毛布でコタツ状態にした事でとても素敵な空間が出来ました。
この時期のキャンプは初めてなので寒さにおびえていたのですが、 薪ストーブ + コタツのおかげで快適に過ごす事ができました。

Image: 20190102_063358447_iOS.jpg

お座敷コタツスタイル

キャンプ場の入口付近で地元のイチゴを買って来ておやつにチョコレートフォンデュを食べたのですが、 テーブルコンロとして OPTIMUS の 8R が大活躍してくれました。

Image: 20190103_054055367_iOS.jpg

OPTIMUS 8R でチョコフォンデュ

温暖な千葉とは言えやはりこの時期は寒い様で、朝起きるとケトルの中の水が凍っていました。
水が凍る様な寒さの中でのキャンプは初めてなのですが何とかなるモンですね。

Image: 20190102_220822246_iOS.jpg

ケトルの中の水が凍結


Copyright © Mitzyuki IMAIZUMI 2008,2009. All rights reserved.