Posted at

PythonワンライナーでMySQL実行履歴を読む


はじめに


やること

MySQL実行履歴は.bash_historyファイルに書かれています。ファイルには

show\040databases;

のように、UTF-8のエスケープシーケンスが含まれた状態で書いてあります。今回はPythonワンライナーを使って、先程の文字列を

show databases;

のように整形して表示しようと思います。


なぜPythonワンライナーなのか

ただの趣味です。


Pythonワンライナー

最初の10行を読む場合は次のようになります。

$ cat /path/to/.mysql_history | python3 -c 'import sys; from signal import signal, SIGPIPE, SIG_DFL; signal(SIGPIPE, SIG_DFL); [sys.stdout.write(line.decode("unicode_escape")) for line in sys.stdin.buffer];' | head -n 10

Python3のコードをワンライナーでない状態で書くと、次のようになります。

import sys

from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE, SIG_DFL)
[sys.stdout.write(line.decode("unicode_escape")) for line in sys.stdin.buffer]

3行目の

signal(SIGPIPE, SIG_DFL)

では、パイプが切断されたときにエラーなく終了させるようにしています。これによりパイプを通じてheadtailを実行しても、PythonでBroken Pipeエラーが発生しなくなります。

4行目の

[sys.stdout.write(line.decode("unicode_escape")) for line in sys.stdin.buffer]

では、標準入力の各行に対して


  • バイト列で読み込む


  • decode("unicode_escape")でエスケープシーケンスを含むバイト列を文字列に変換

を行っています。リストの内包表記を使用しているのは、ワンライナーで一行ずつ処理するために仕方なく… インデントが使えないのはつらいですね。


最後に

ワンライナーを書くときはPerlの方がいいですね。