結局Terminatorに戻った件。

ターミナルエミュレータを物色する。でいろいろと物色してみたんですが、結局また Terminator に戻ってきてしまいました。まあそれはいいんですが。

なので Terminator のキーバインドを自分用にメモ。というのも、設定から "PuTTY style paste"(右クリックでペースト)を指定したら、それまで右クリックで出ていた分割とか設定とかのコンテキストメニューが出なくなってしまったから。当然ですが。

まず設定メニューを出すにはマウスの右クリックですが、キーバインディングではできなさそうです。"PuTTY style paste" をチェックすると、マウスの中央ボタンがコンテキストメニュー起動になります。中央ボタンが効かない場合には、$HOME/.config/terminator/config ファイルを直接編集して無効にすればよいです。
それからSuperキーというのが出てきますが、いわゆる "Win" キーのことです。

キー 動作 キー 動作
F1 HTMLヘルプ C+S+カーソル ドラッグバーの移動
C+S+O 水平に分割 C+S+PageDown タブ位置を次のタブと入れ替え
C+S+E 垂直に分割 C+S+PageUp タブ位置を前のタブと入れ替え
C+S+T 新規タブ C+S+C 選択部分をコピー
C+S+I 新規Window C+S+V 貼り付け
Alt+LL レイアウトランチャー C+S+S スクロールバー表示のトグル
C+S+W 現在のターミナルを閉じる C+S+F 前方向検索
C+S+Q 現在のウィンドウを閉じる C+S+R ターミナルリセット
A+カーソル ターミナル間の移動 C+'+' フォントサイズ拡大
C+PageDown 次のタブに移動 C+'-' フォントサイズ縮小
C+PageUp 前のタブに移動 C+0 フォントサイズリセット
C+Tab/C+S+N 同一タブの次のターミナルに移動 C+A+W ウィンドウタイトル変更
C+S+Tab/C+S+P 同一タブの前のターミナルに移動 C+A+X ターミナルタイトル変更
Super+I 新規のTerminatorプロセス起動 F11 フルスクリーン切り替え

Chromiumでkeyringの入力を求められる件。その3

Chromiumでkeyringの入力を求められる件。で、もっと簡単な方法がありました。

Manjaro Linux Xfce4 版のみかもしれませんが、メニューから「設定」→「セッションと起動」に進みます。
そこで「SSH鍵エージェント(GNOMEキーリング:SSHエージェント)」と「シークレットストレージサービス」、「証明書および鍵を格納するストレージ」の3つにチェックを入れます。
これでログイン時に自動的に GNOME キーリングを起動してくれます。

ただし自動ログインではやっぱりダメなようです。

ターミナルエミュレータを物色する。

Manjaro をいじっていると、ターミナルエミュレータがデフォルトのものではちょっと不便さを感じてしまうので、物色してみました。

pacman -Ss terminalするとずらーっと出てきますが、そこからピックアップ。条件としては、せっかく軽い Xfce4 を使っているのだから軽いもの、かつタイル分割できるもの。なので Gnome とか KDE 系のものは一旦パス。
  • community/alacritty 0.2.9-1
    A cross-platform, GPU-accelerated terminal emulator
    依存パッケージ: freetype2 fontconfig xclip libxi libxcursor
  • community/jupyter_console 6.0.0-1
    An IPython-like terminal frontend for Jupyter kernels in any language.
    依存パッケージ: ipython python-jupyter_client python-ipykernel python-pygments python-prompt_toolkit
  • community/kitty 0.13.3-1
    A modern, hackable, featureful, OpenGL based terminal emulator
    依存パッケージ: python3 freetype2 fontconfig wayland libx11 libxkbcommon-x11 hicolor-icon-theme libgl
  • community/nyancat 1.5.2-1
    Nyancat rendered in your terminal.
    依存パッケージ: glibc
  • community/qterminal 0.14.1-1 (lxqt)
    A lightweight Qt-based terminal emulator
    依存パッケージ: hicolor-icon-theme qtermwidget qt5-x11extras
  • community/rxvt-unicode 9.22-7
    Unicode enabled rxvt-clone terminal emulator (urxvt)
    依存パッケージ: rxvt-unicode-terminfo libxft perl startup-notification libnsl
  • community/sakura 3.6.0-2
    A terminal emulator based on GTK and VTE
    依存パッケージ: vte3 libxft
  • community/terminator 1.91-6
    Terminal emulator that supports tabs and grids
    依存パッケージ: gsettings-desktop-schemas libkeybinder3 libnotify python2-cairo python2-dbus python2-psutil python2-gobject vte3 xdg-utils
  • community/sl 5.02-5
    Steam Locomotive runs across your terminal when you type "sl" as you meant to type "ls".
    依存パッケージ: ncurses
  • community/termite 14-2
    A simple VTE-based terminal
    依存パッケージ: gtk3 pcre2 gnutls vte-common termite-terminfo
  • community/tilix 1.9.0-1
    A tiling terminal emulator for Linux using GTK+ 3
    依存パッケージ: libx11 gtkd vte3 dconf gsettings-desktop-schemas
おかしなのも紛れ込んでいますがこんなものでしょうか。コアというか、ターミナルエミュレータ本体の部分は vte を組み込んでいるのが多いようです。

以前は Terminator を使っていたのですが、ちょっと重たい感じです。なので軽いものがいいな、と。
OpenGL を使って高速化しているのが alacritty と kitty。軽そうなのが termite とか sakura あたりでしょうか。"best terminal emulator linux" で検索するといくつかランキングページがでてくるのでそれも参考にしつつ。ちなみに termite というのはシロアリのことだそうです。

Sakura を使ってみたら、タイル型ではなくタブ型でした。なぜタイリングにこだわるかというと、サーバのログを "tail -f" で表示させながらエラー確認をすることが多いからです。

Termite は画面もシンプルで軽く、またモーダルというのがおもしろいです。ArchLinux に説明のページがあります。が、tiling という言葉があったので誤解したのですが、どうやらこれは「タイリング型のウィンドウマネージャ」ということらしいです。ちょっと使った感じとしては軽くていいのですが…。

Alacritty は GPU を使うということで、どのくらい使用するのかはわかりませんがスクロールなどは素早い印象です。

Kitty はタイリングというよりはマルチウィンドウみたいな感じで、ちょっと好みと違うかな。

とりあえず Alacritty がスタイル的に合いそうな気がするので、ちょっと使ってみたのですが、タイリングの部分は tmux を利用するようで、これはちょっとないかな。Alacritty は Windows 版もあるようですが、何が走るんだろう。設定などは Alacritty Wiki にあります。

結局また Terminator に戻りそうです。

それからターミナルエミュレータで256色を表示してみたいときには、show-all-256-colors.pyなんかを使うと手軽に表示できます。

Chromiumでkeyringの入力を求められる件。その2

Chromiumでkeyringの入力を求められる件。がその2に続いてしまいました。

su をすると /etc/profile.d/keryring.sh がエラーを出してきます。
% su
パスワード:
** Message: 08:21:18.322: couldn't access control socket: /run/user/1000/keyring/control: 許可がありません
** Message: 08:21:18.326: couldn't connect to dbus session bus: Could not connect: 許可がありません
** Message: 08:21:18.326: The gnome-keyring control directory cannot be accessed: /run/user/1000/keyring: 許可がありません

** (gnome-keyring-daemon:23044): WARNING **: 08:21:18.326: couldn't create socket directory: /run/user/1000/keyring-UERQ0Z: 許可がありません

** (gnome-keyring-daemon:23044): WARNING **: 08:21:18.326: couldn't bind to control socket: /run/user/1000/keyring-UERQ0Z/control: 許可がありません

これは無視しておけばいいんですが、ちょっとかっこ悪い。なのでなんとか対策を考えます。

su して superuser になると、UID が 0 になります。なのでこれを使ってみます。

/etc/profile.d/keyring.sh:
if [ $UID -ne 0 ]; then
  eval $(/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh)
  export SSH_AUTH_SOCK
fi

これでいいかどうか、ですが、基本的に root ログインはしないこと、root ログインするようなときはコンソールからになるだろうし、そこでウェブブラウザを使うような危険なことはしないことなどを考えると、いいんじゃないでしょうか。

Chromiumでkeyringの入力を求められる件。

Manjaro Linux で Chromium を立ち上げたときに、keyring が開けないといってパスワードを毎回求められるのが鬱陶しいです。Firefox とかでは出ないのに。
で、空のパスワードを設定するといいよ、という対策が引っかかってくるんですが…。Manjaro だと別のパッケージを新たにインストールすることになりますが、それはなんだか嫌です。それに空のパスワードを設定するのも気持ち悪いです。

追記: Chromiumでkeyringの入力を求められる件。その3でもっと簡単な方法を書きました。

Chromium keyring change?に方法が書かれていましたので、翻訳しておきます。

もし keyring パスワードにログインパスワードと同じものを設定しているなら 4 に飛んでください。
  1. ~/.local/share/keyrings内のファイルを削除します。
  2. Chromium を開きます。
  3. パスワード作成のダイアログが出てきたら、ユーザアカウントのパスワードと同じものを設定します。
  4. 以下の内容を /etc/pam.d/login の最後に追加します。
    auth       optional     pam_gnome_keyring.so
    session    optional     pam_gnome_keyring.so        auto_start
  5. 以下の内容を /etc/pam.d/passwd の最後に追加します。
    password    optional    pam_gnome_keyring.so
  6. 以下の内容で /etc/profile.d/keyring.sh を作成します。
    eval $(/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh)
    export SSH_AUTH_SOCK
  7. 一旦ログアウトして再度ログインします。
ホームディレクトリのドットファイルを整理する。でも書いていますが、/etc/profile.d/*.shはログイン時に読み込まれ、実行されるようになっていますので、上記の keyring.sh は自動で実行されます。

ログインパスワードを変更した場合には上記の動作は無効になりますので、再度1から3をやり直すか、seahorseを使って新しいパスワードを設定する必要があります。
また、この方法は PC の起動時に自動ログインの設定がしてあると、うまく行きません。

だそうです。

ホームディレクトリのドットファイルを整理する。

UNIX 系の OS で、ちょっと悩ましいのは $HOME(ホームディレクトリ)にドットファイルが増えてしまうことです。

ls -a すると表示されるリストの8割以上がドットファイルとか、もう許して下さいな感じです。

% ls -a
.              .aliases~                        .dbus        .hgignore   .profile         .xinitrc              .zshrc~    __pycache__
..             .bash_history                    .dir_colors  .hgignore~  .python_history  .xprofile             Desktop    bin
.ICEauthority  .bash_logout                     .dmrc        .hgrc       .ssh             .xsession-errors      Documents  build
.Xauthority    .bash_profile                    .esd_auth    .hgrc~      .texlive         .xsession-errors.old  Downloads  work
.Xclients      .bashrc                          .gem         .lesshst    .thumbnails      .zcompdump            Music
.Xmodmap       .cache                           .gkrellm2    .local      .thunderbird     .zsh                  Pictures
.Xmodmap.orig  .chrome-remote-desktop-session   .gnupg       .mozc       .vim             .zshenv               Public
.Xmodmap~      .chrome-remote-desktop-session~  .gvimrc      .mozilla    .vimrc           .zshenv~              Templates
.aliases       .config                          .hg          .pki        .wget-hsts       .zshrc                Videos

編集した結果バックアップファイルやらコピーを残してるのやらありますが、まあざっとこんな感じ。もうちょっと整理して数を減らしたいところです。
このときに頼りになるのが XDG Base Directory Specification。それを規格から実装に照らして説明してくれているのがこちら

なので一つ一つやっていきます。環境は Manjaro Linux XFCE 版なので、他のディストロは適当に読み替えてください。

システム

システム側であらかじめ設定されているのは以下の環境変数です。
XDG_SESSION_ID=c5
XDG_RUNTIME_DIR=/run/user/1000
XDG_SESSION_TYPE=tty
XDG_SESSION_CLASS=user
また、ユーザ側で設定しておきたいのは以下の環境変数です。
XDG_CONFIG_HOME=$HOME/.config
XDG_CACHE_HOME=$HOME/.cache
XDG_DATA_HOME=$HOME/.local/share
XDG_RUNTIME_DIR はユーザごとに設定される /var/run みたいなものです。デフォルトではユーザIDが振られています。必要なら設定すればよいでしょう。
それとは別に、/etc/xdg に設定ファイルがいくつか置かれています。ただしこれらは ssh ログイン時などには読み込まれないようなので、ここでは置いておきます。
ここでは、お仕着せでシステムワイドに設定する方向で進めていきます。

bash

まずは標準の shell の bash。Manjaro の場合には、次の順序で読み込まれるようです。bash -l -v で確認しました。つまりログインシェルの場合。
  1. /etc/profile
  2. /etc/profile.d/*.sh
    /etc/profile から呼ばれる。アルファベット順に読み込まれる。アプリケーションごとに必要な設定はここ。ロケールもここ。
  3. /etc/bash.bashrc
    /etc/profile から呼ばれる。システムワイドの bash 設定を行う。プロンプトや $TERM の設定はここ。
  4. /usr/share/bash-completion/bash_completion
    もしあれば読み込まれる。Manjaro にはない。
  5. $HOME/.bash_profile
    $HOME/.bashrc を source しているだけ。
  6. $HOME/.bashrc
    ユーザの環境変数とか alias とかいろいろと設定する。
  7. プロンプトが表示されて bash 起動完了。
  8. $HOME/.bash_logout
    ログアウト時に読み込まれる。何もしていない。
  9. /etc/bash.bash_logout
    ログアウト時に読み込まれる。何もしていない。
bash の場合にはユーザごとのドットファイルはハードコードされているようなので、ドットファイル類を .config/bash に移動することは(現状では)できません。ただ、他のアプリケーションのための設定は必要なので、ここでは /etc/profile.d/xdgenv.sh あたりで XDG ユーザ変数を設定するようにすればよいでしょう。そうすることで他の shell からも source することができます。
/etc/profile.d/xdgenv.sh:
# Set user variables based on XDG Base Directory Specification.
#

export XDG_CONFIG_HOME=$HOME/.config
export XDG_CACHE_HOME=$HOME/.cache
export XDG_DATA_HOME=$HOME/.local/share

zsh

zsh では環境変数 ZDOTDIR が設定されているとそこを見に行きます。
  1. /etc/zsh/zshenv
    本来は /etc/zshenv を読みにいく(manページの説明)ようだが、Manjaro では /etc/zsh/zshenv を読みにいく。
  2. $ZDOTDIR/.zshenv
    環境変数 ZDOTDIR が指定されていれば $ZDOTDIR/.zshenv を、指定されていなければ $HOME/.zshenv を読む。
  3. /etc/zsh/zprofile
    Manjaro では /etc/zsh/zprofile の中身は emulate sh -c 'source /etc/profile' となっていて、/etc/profile を読み込む。/etc/profile の読み込むものは bash と同じ。
  4. $ZDOTDIR/.zprofile
    ZDOTDIR が指定されていなければ $HOME/.zprofile を読み込む。
  5. /etc/zsh/zshrc
  6. $ZDOTDIR/.zshrc
  7. /etc/zsh/zlogin
    ログインシェルの場合に読み込まれる。
  8. $ZDOTDIR/.zlogin
    ログインシェルの場合に読み込まれる。
  9. プロンプトが表示されて bash 起動完了。
  10. $ZDOTDIR/.zlogout
    ログアウト時に読み込まれる。何もしていない。
  11. /etc/zsh/zlogout
    ログアウト時に読み込まれる。何もしていない。
ということなので、bash のところで /etc/profile.d/xdgenv.sh を作成していれば、XDG* はそこで設定されます。また、/etc/zsh/zshenv があれば一番最初に読み込まれるので、ZDOTDIR をそこで設定すればいいのですが、ZDOTDIR=$XDG_CONFIG_HOME/zsh とする必要があるため、二重に読み込むことになりますが以下のようにします。
# /etc/zsh/zshenv
# set ZDOTDIR respecting XDG Base Directory Specification
#

emulate sh -c 'source /etc/profile'
export ZDOTDIR=$XDG_CONFIG_HOME/zsh
また、標準ではコマンドヒストリは $HOME/.zsh/histfile に保存されますが、これを $XDG_CACHE_HOME/zsh/history に変更します。コマンドヒストリはユーザ設定なので、これは $XDG_CONFIG_HOME/zsh/.zshrc で設定し直します。
$XDG_CONFIG_HOME/zsh/.zshrc:
HISTFILE=$XDG_CACHE_HOME/zsh/hisotry
zstyle :compinstall filename '$ZDOTDIR/.zshrc'
これで $HOME から zsh 関連のドットファイルは削除できます。

git

0d94427eから XDG_CONFIG_HOME に対応しているので、$XDG_CONFIG_HOME/git/config を使います。

Neovim

Neovim は最初から XDG Base Directory Specification に沿うように作られているので、$XDG_CONFIG_HOME/nvim を利用すれば問題ありません。
ここで、vim からも同じ設定を使えるように init.vim などを記述しておくと、nvim でも vim でも同じように使えます。

vim

vimはちょっとややこしいです。前述の ArchLinux の Wiki に書いてあるように、.vimrc などは基本的にハードコードされています。が、別途 VIMINIT=":source $XDG_CONFIG_HOME"/vim/vimrcを shell の設定時に行っておけば、vim の起動時に $VIMINIT を参照してくれます。
なので $ZDOTDIR/.zshenv に設定しておきます。ここでは vim と nvim の設定を共通にすることを考えているので、あえて $XDG_CONFIG_HOME/nvim/vimrc にします。ただし、undodir などが一緒になると問題があるかもしれないので、そこは別にしておきます。Manjaro の場合には vim は標準ではインストールされていなくて、ex および vi が標準なので、あえて vim をインストールせずに alias vim=nvim するのもアリかもしれません。
# .zshenv

PATH1=$HOME/bin
export PATH=$PATH:$PATH1

export QT_SELECT=5
export GTK_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export QT_IM_MODULE=fcitx

# better yaourt colors
export YAOURT_COLORS="nb=1:pkg=1:ver=1;32:lver=1;45:installed=1;42:grp=1;34:od=1;41;
5:votes=1;44:dsc=0:other=1;35"

# env for locate updatedb for local files.
export PRUNEPATHS="`echo $HOME/.cache/[a-ce-z]*`"
export PRUNEPATHS="`find $HOME -name \".hg\" -printf \"%p \"` $PRUNEPATHS"
export PRUNEPATHS="$HOME/.mozilla $HOME/.dbus $HOME/.thumbnails $HOME/.thunderbird $
PRUNEPATHS"
export LOCATE_PATH=$XDG_CACHE_HOME/mlocate.db

export VIMINIT=":source $XDG_CONFIG_HOME"/nvim/vimrc
また、vimrc は以下の内容にします。
" vim:set et ts=2 sts=2 sw=2 tw=0 fenc=utf-8:
" _vimrc : initialization file for Vim.
" just source init.vim for commonnization.
"
" Modified: 9 Apr 2018
"
source $XDG_CONFIG_HOME/nvim/init.vim

" mswin.vim maps those keys when gui=yes.
" this is terrible and should be unmapped.
if has('gui')
  unmap <C-f>
  iunmap <C-f>
  cunmap <C-f>

  unmap <C-h>
  iunmap <C-h>
  cunmap <C-h>
endif

mercurial

$HOME/.hgrc は $XDG_CONFIG_HOME/hg/hgrc に移動することができます。が、.hgignore はそのディレクトリ以下の ignore ファイルを指定しているため、移動できません。また .hg ディレクトリはリポジトリのため、移動できません。

その他

.ICEauthority

libice が作成するファイルですが、Use XDG base directory instead of $HOME for .ICEauthorityで議論され、パッチがあげられ、2019年3月25日に push されているので、いずれマージされるでしょう。
それまでは触らないでおくか、export ICEAUTHORITY="$XDG_RUNTIME_DIR"/ICEauthority を /etc/zsh/zshenv あたりに入れておけばよいでしょう。ただ、環境変数がやたら増えるのも困りものですから、ここでは放置しておきます。

.Xauthority

同上です。export XAUTHORITY="$XDG_RUNTIME_DIR"/Xauthority

.Xmodmap

対応策はなさそうです。

.dircolors

source "$(dircolors "$XDG_CONFIG_HOME"/dircolors)" を $ZDOTDIR/.zshenv あたりに入れておきます。bash のほうは $HOME/.bashrc のdircolors に関する部分の変更が必要です。

.mozc

移動できません。ソースを見ましたが、XDG_CONFIG_HOME を参照している部分はありませんでした。

.mozilla(firefox)

$XDG_CONFIG_HOME/mozilla と $XDG_CACHE_HOME/mozilla と $XDG_DATA_HOME/mozilla がある場合にはそちらを使うようです。
なので、以下のようにします。
$ mkdir .config/mozilla
$ mkdir .cache/mozilla
$ mkdir .local/share/mozilla
$ chmod 700 .config/mozilla .cache/mozilla .local/share/mozilla

.python_history

Python がインタラクティブモードで起動されると readlline が作成するようです。今のところ移動できません。

.texlive

ハードコードされているようで変更できません。

.thumbnails

$XDG_CACHE_HOME/thumbnails/ があればそちらを使うようです。

.thunderbird

ハードコードされているようで変更できません。

.xinitrc

基本的には DesktopManager(lightdmやgdmなど)を使っていれば xinit を呼ぶことはないので不要なはずですが、export XINITRC="$XDG_CONFIG_HOME"/X11/xinitrc を指定することで xinit は参照してくれます。

.gnupg

export GNUPGHOME="$XDG_CONFIG_HOME"/gnupgすることで参照してくれます。

Jcode.pmではなくてEncode.pmを使う。

自分のPerlに関する情報は10年以上前から止まってた、ということですね。
Jcode.pm - jcode.pl の後継、Encode.pm への架け橋というページで、2008年5月に
Perl 5.8.0 より、Jcodeの全機能は Encode module を通じてPerlに標準装備となります。Jcodeのメンテナンスは旧Perlのために 今後も続けていく所存ですが、最新のPerlをお使いの方には、より高機能、高 性能、そしてなんといっても標準装備の Encode の方をお薦めします。
ということだそうで、現在の環境では Jcode.pm ではなくて Encode.pm(Encode::JP) を使うのがよい、と。Encode.pm は core に取り込まれてるんですね。

未だにサーバには jcode.pl を使った古典的CGIアプリが走っているので、最近のサーバのトレンドに合わせて FastCGI と SQLite を使うように書き直して、あるいはもしかしたら PHP とか Python あたりで書き直したほうがいいのかも。

MercurialとPython3。その2

MercurialとPython3。のところではその時点でのステータスを拾ってきていたんですが、どうやら編集されているようです。
1. Status
Mercurial 5.0 is the first release that officially has beta support for Python 3. Supported Python 3 versions are 3.5, 3.6, and 3.7. Python 3.8 mostly works, but there are a few known incompatibilities. Mercurial with Python 3 on Windows is not yet widely tested and there are more known issues on Windows compared to Linux, macOS, and other UNIX-like platforms.

It is the project policy for Mercurial and its core extensions to be compatible with Python 3. Over 99% of tests pass with Python 3 and test regressions are treated seriously.

Many 3rd party extensions have not yet been ported to work with Python 3.

Mercurial 5.0 は公式に Python 3 をベータサポートする最初のリリースです。サポートされる Python 3 のバージョンは 3.5、3.6 および 3.7 です。Python 3.8 はほとんど動きますが、いくつかの既知の適合性の不一致があります。Windows での Python 3 の Mercurial はまだ十分にテストされておらず、Linux、macOS およびタの UNIXライクなプラットフォームに比べて多くの既知の問題があります。

Mercurial とそのコアエクステンションが Python 3 と適合していることはプロジェクトのポリシーです。Python 3 では 99% を超えるテストをパスし、回帰テストは慎重に行われています。

多くのサードパーティエクステンションはまだ Python 3 で動くようにポーティングされてはいません。

らしいです。
前のエントリでは 5月1日リリースという目標だったようですが、さて。

Apacheのmod_cgiとmod_cgidとpreforkとevent。

自分用メモ。

  • mod_cgi
    Unix でマルチスレッドの MPM を使っている場合は、このモジュールの 代わりに mod_cgid を使う必要があります。 ユーザレベルではこの二つのモジュールは本質的には同一です。
  • mod_cgid
    Unix オペレーティングシステムの中には、マルチスレッドのサーバから プロセスを fork するのが非常にコストの高い動作になっているものがあります。 理由は、新しいプロセスが親プロセスのスレッドすべてを複製するからです。 各 CGI 起動時にこのコストがかかるのを防ぐために、mod_cgid は子プロセスを fork して CGI スクリプトを実行するための 外部デーモンを実行します。 主サーバは unix ドメインソケットを使ってこのデーモンと通信します。

    コンパイル時にマルチスレッド MPM が選ばれたときは mod_cgi の代わりに必ずこのモジュールが使用されます。 ユーザのレベルではこのモジュールの設定と動作は mod_cgi とまったく同じです。唯一の例外は ScriptSock ディレクティブの 追加で、このディレクティブは CGI デーモンとの通信用のソケットの名前を 指定します。
  • prefork
    このマルチプロセッシングモジュール (MPM) は、 Unix 上での Apache 1.3 のデフォルトの挙動と非常によく似た方法で リクエストを処理する、スレッドを使わず、先行して fork を行なう ウェブサーバを実装しています。 スレッドセーフでないライブラリとの互換性をとるために、 スレッドを避ける必要のあるサイトでは、このモジュールの使用が適切でしょう。 あるリクエストで発生した問題が他のリクエストに影響しないように、 個々のリクエストを単離するのにも、最適な MPM です。
  • event
    The event Multi-Processing Module (MPM) is designed to allow more requests to be served simultaneously by passing off some processing work to the listeners threads, freeing up the worker threads to serve new requests.

    event is based on the worker MPM, which implements a hybrid multi-process multi-threaded server. A single control process (the parent) is responsible for launching child processes. Each child process creates a fixed number of server threads as specified in the ThreadsPerChild directive, as well as a listener thread which listens for connections and passes them to a worker thread for processing when they arrive.

    event マルチプロセッシングモジュール(MPM)は、処理動作のいくつかをリスナースレッドに受け渡し、新しいリクエストを扱うためにワーカースレッドを開放することによって、より多くのリクエストを同時に受け入れるように設計されている。
    event は、マルチプロセスとマルチスレッドのハイブリッドサーバである worker MPM をベースとしている。一つのコントロールプロセス(親)が子プロセスの起動を行う。それぞれの子プロセスは ThreadPerChild ディレクティブで指定された固定数のサーバスレッドを、接続を待ち受けてそれを処理するためにワーカースレッドに受け渡す一つのリスナースレッドと同時に生成する。
  • worker
    このマルチプロセッシングモジュール (MPM) は、マルチスレッドとマルチプロセスのハイブリッド型サーバを 実装しています。リクエストの応答にスレッドを使うと、 プロセスベースのサーバよりも少ないシステム資源で、 多くのリクエストに応答することができます。 それにもかかわらず、多くのスレッドを持った複数のプロセスを 維持することで、 プロセスベースのサーバの持つ安定性も保持しています。
というようなことをまとめてみると、prefork はマルチプロセス、event と worker はマルチプロセス/マルチスレッドということになります。スレッドセーフじゃない CGI は prefork のほうがいい、でも prefork はリソースを食うから、スケーラビリティが重要ならスレッドセーフにして event か worker を使う、という感じでしょうか。
一方でこういう記事を見つけました。
ApacheでCGIを使う場合にpreforkを使った方が良い状況とそのチューニングについて。ここでは mod_cgid がシングルプロセスであるため、そこがボトルネックになってリクエストを取りこぼす状況がありうるということが示唆されています。一方 mod_cgi はリクエストごとに個別にプロセスを起動するため、マルチスレッドではないがマルチプロセスが有効に働いてかなりいい数値を出してきています。もちろんこれは PC のコア数、アプリケーションの処理内容とか DB へのアクセスなどの複合要因で変わってくるとは思いますが、シナリオによっては prefork のほうがよい場合がある、ということを示唆しています。

(以下の表は作成中に付き嘘がいっぱいかもしれない)

MPM 実装 CGI FastCGI Perl Python PHP
prefork マルチプロセス mod_cgi mod_fcgi mod_cgi
mod_fcgi
mod_proxy_uwsgi mod_php
worker マルチプロセス
マルチスレッド
mod_cgid mod_proxy_uwsgi php_fpm
event マルチプロセス
マルチスレッド
mod_cgid mod_proxy_fcgi mod_proxy_uwsgi php_fpm
ちょっと分かりづらいので、もうちょっと分類してみようと思います。
  • mod_cgi
    prefork の場合には mod_cgi が使われる。
  • mod_cgid
    event および worker の場合には mod_cgid が使われる。ScriptSock ディレクティブが追加されていて、UNIX ソケットを扱える。
  • mod_mime
    AddHandlerは mod_mime がサポートしている。
  • mod_alias
    ScriptAliasは mod_alias がサポートしている。
  • mod_proxy
    Apache は他の CG Iへのインタフェースのために PROXY モジュールを利用する。ProxyPassは mod_proxy がサポートしている。
  • mod_proxy_fcgi
  • mod_proxy_scgi
  • mod_proxy_uwsgi
  • uWSGI Perl support (PSGI)
    PSGI とカッコ書きで書いてあるとおり、PSGI へのインタフェースを提供するもの。つまり Plack のようなミドルウェアが必要となるし、PSGI daemon(もしくはサーバ)が必要となる。
  • Running PHP scripts in uWSGI
  • Running CGI scripts on uWSGI
    これは CGI 実行のためのサーバなどを必要としないので、イメージとしては uWSGI が CGI プログラムを実行してそれを ポートあるいはソケット経由で Apache や Nginx に提供する形になる。mod_cgi を mod_cgid + uWSGI with CGI plugin で置き換える感じ。
  • PSGI/Plack
  • Perl CGI
  • mod_http2
    MPM Configurationによれば、prefork では mod_http2 はたった一つのコネクションしか扱えないためにサーバがストールするため、ベストな選択は event を使うこと。
  • ProxyPass ディレクティブ
  • mod_wsgi
  • mod_fcgid
    リポジトリを見ると、2.3.9(最新版)がリリースされたのは2013年10月。Apache 2.5 のドキュメントは用意されているようだが、メンテナンスされているのかどうかは不明。fcgi + mod_proxy_fcgid のほうがよいかも。

こうしてピックアップしてみると、Webアプリケーションをサーバで動かすにはいろいろと方法があって、どれが最適化はそのアプリケーション(あるいは言語やプラットフォーム)によるし、唯一無二のベストなソリューションはない、というか、ないからこそいろいろな方法があるんでしょうね。

CGI でふと思い出したけれど、Wikiエンジンで一番最初に触れた TWiki は Perl で動かしていたのでした。

Perl 関連:
(作成中)
CGI::Alternativesによれば、
(他の言語でもそうだけれど)コード中に html コードを組み込むのではなく、Perl コードと HTML コードを分離してテンプレート化して利用するほうがよい。CGI.pm は 5.22 以降ではすでに core から外されて、標準ライブラリではなくなっている。コードとHTMLを切り離すテンプレート方式を強く推奨するし、新規で開発するなら MojoliciosDancer2CatalystあるいはPSGI/Plackを使うべき。常に使われるような軽めのアプリケーションなら Mojolicios か Dancer2 を、大きいアプリケーションなら Catalyst を検討したほうがよい。
という感じ。
Plack/PSGI のインストールは Handbook を参考に。
太古のCGIプログラム
CGIプログラム
CGI::Fastプログラム
Plackプログラム

(余談)
Manjaro では Plack のパッケージがなかったため、CPAN からインストールしたらぞろぞろとたくさんのパッケージがインストールされた。
Apache-LogFormat-Compiler-0.35-0  File-ShareDir-1.116-0         LWP-MediaTypes-6.04-0           Test-LeakTrace-0.16-0
Class-Inspector-1.34-0            File-ShareDir-Install-0.13-0  List-MoreUtils-0.428-0          Test-MockTime-0.17-0
Cookie-Baker-0.10-0               Filesys-Notify-Simple-0.13-0  List-MoreUtils-XS-0.428-0       Test-Requires-0.10-0
Cpanel-JSON-XS-4.11-0             HTTP-Date-6.02-0              Module-Build-0.4229-0           Test-SharedFork-0.35-0
Devel-StackTrace-2.03-0           HTTP-Entity-Parser-0.21-0     Module-Build-Tiny-0.039-0       Test-TCP-2.19-0
Devel-StackTrace-AsHTML-0.15-0    HTTP-Headers-Fast-0.22-0      POSIX-strftime-Compiler-0.42-0  Test-Time-0.07-0
Encode-Locale-1.05-0              HTTP-Message-6.18-0           Params-Util-1.07-0              Test-Warnings-0.026-0
Exporter-Tiny-1.002001-0          HTTP-MultiPartParser-0.02-0   Plack-1.0047-0                  Try-Tiny-0.30-0
ExtUtils-Config-0.008-0           Hash-MultiValue-0.16-0        Stream-Buffered-0.03-0          WWW-Form-UrlEncoded-0.25-0
ExtUtils-Helpers-0.026-0          IO-HTML-1.001-0               Test-Deep-1.128-0
ExtUtils-InstallPaths-0.012-0     JSON-MaybeXS-1.004000-0       Test-Fatal-0.014-0

Apache で FastCGI アプリケーションを動作させる方法は現実的には二通りで、mod_fcgid を使って Apache にサーブさせる方法と、mod_proxy_fcgi を使って他の FastCGI サーバへの proxy をさせる方法がありますが、mod_fcgid はApache のパッケージには含まれていないため今後どうなるかが不明なのと mod_fcgid 自体がパフォーマンスを優先するためかリソースをどか食いするらしいこと、どうやら時代の流れ的には uWSGI にしても PSGI にしてもそうですがアプリケーションの管理は外部のサーバに任せて、Apache 自体は PROXY を通して利用する、という方向なのかなという感じ。Perl の場合には Plack を使うか、fcgiwrap + spawn-fcgi でサーブさせるか、の二通りがありそうです。
spawn-fcgi は lighttpd に含まれているようです。


Python 関連:
(作成中)
uWSGI
GNU Mailmanは、Mailman 2.1 は Python 2.7 でかつ CGI/1.1 API が必要、Mailman 3 は Python 3.4 以降で WSGI が必要、ということなので、もしかして Django ベースのアプリを使わないなら CGI あるいは FastCGI で十分に足りてしまいそうな予感。というかそれがベストかもしれません。

PHP 関連:
(作成中)
PHP で使うアプリは今のところ WordPress のみなので、php-fpm を使って FastCGI で構築すればよさそうです。

ということは、Perl も含めて、Apache の FastCGI(mod_proxy_fcgi) で全部扱えそうな感じです。

pacmanについて。

Manjaro Linux とか Arch Linux とか MSYS2 とかは、パッケージ管理に pacman を使用しています。pacman はもともとが Arch Linux のパッケージ管理のために開発されており、Arch Linux をベースとした Manjaro Linux や FreeBSD をベースとした PacBSD で採用されています。
その他のパッケージマネージャとしては RedHat Linux が開発した rpm(とそれをベースとした yum)、Debian Linux が開発した dpkg(とそれをベースとした aptなど)、NetBSD が開発した pkgsrc システムなどがあります。

で、ここでは最近 NetBSD と並行して使い始めた Manjaro Linux で採用している pacman について、簡単にまとめておきます。つまり自分用メモ。

動作 指定オプション 説明
インストール -S [パッケージ名] ひとつ、あるいは複数のパッケージをインストールする。
依存パッケージがあればそれもインストールされる。
パッケージ名の代わりにグループ名も指定できる。
インストール -Sg [グループ名] グループ名で指定されたグループに含まれるパッケージ名を表示する。
削除 -R [パッケージ名] 特定のパッケージのみ削除する。
削除 -Rs [パッケージ名] 特定のパッケージと、そのパッケージのみが依存しているパッケージを削除する。
アップグレード -Syu リポジトリデータベースと同期して、アップグレードがあるシステム内のパッケージをすべてアップグレードする。
部分的なアップグレードはサポートされていない。
検索 -Ss [検索ワード] 指定された検索ワードにマッチするものがリポジトリにあれば表示する。
検索 -Qs [検索ワード] インストール済みのパッケージから検索する。
検索 -Si [パッケージ名] パッケージに関する詳しい情報を表示する。
検索 -Qi [パッケージ名] インストール済みのパッケージに関する詳しい情報を表示する。
検索 -Ql [パッケージ名] パッケージによってインストールされたファイルの一覧を表示する。
検索 -Qo [/パス/ファイル名] どのパッケージがそのファイルをインストールしたかを表示する。
検索 -Qdt 依存関係のない孤立したパッケージの一覧を表示する。
キャッシュの削除 -Sc ダウンロードしたパッケージファイルをキャッシュから削除する。
警告が出た -Syuu ローカルの[パッケージ]のほうが最新です というメッセージが出たときに

あるパッケージを導入して、そのパッケージが依存するパッケージもいくつかインストールされたけど、不要になって依存関係ごと削除したくなったら "-Rs" を使えばいいわけですね。

pacman -Sh すると、"-S" 関連のオプションフラグ一覧を表示してくれます。

オプション 意味
-y サーバーから最新のパッケージデータベースをダウンロード
-u インストールしたパッケージのアップグレード
-uu でダウングレードを有効
とかなっていて、"-Syuu" は必要があればダウングレードも行うってことでしょうか。pacman の man page を見ると、
-u, --sysupgrade
Upgrades all packages that are out-of-date. Each currently-installed package will be examined and upgraded if a newer package exists. A report of all packages to upgrade will be presented, and the operation will not proceed without user confirmation. Dependencies are automatically resolved at this level and will be installed/upgraded if necessary.

Pass this option twice to enable package downgrades; in this case, pacman will select sync packages whose versions do not match with the local versions. This can be useful when the user switches from a testing repository to a stable one.

Additional targets can also be specified manually, so that -Su foo will do a system upgrade and install/upgrade the "foo" package in the same operation.
現在異ストールされているそれぞれのパッケージについて検査し、新しいものがあればアップグレードする。必要があれば依存関係についても自動的に解決されてインストール/アップグレードが行われる。
このオプションを二重("-uu")に指定するとダウングレードを可能にする。この場合、pacman はローカルのバージョンと一致しないパッケージを選択する。これは "testing" リポジトリから "stable" リポジトリに切り替える場合などに重宝する。
また追加のターゲットを手動で指定することもでき、"-Su foo" はシステムアップグレードを行ってかつ "foo" パッケージをインストール/アップグレードも同時に行う。

"-Syuu" を指定すると、どうやらリポジトリの最新バージョン(stable?)に同期するようにローカルにある「リポジトリよりも新しいパッケージ」をダウングレードするようです。おそらくは何らかの理由(バグなど?)によってパッケージがリポジトリから削除された場合などに、ローカルのほうがその削除パッケージをインストールしてしまっていたときには、一つ前のバージョンなどにダウングレードする、というような動作でしょうか。

ManjaroLinuxでChrome Remote Desktopを有効にする。

以前には設定して使ってたのですが、Chromium 自体がなぜか CPU 時間をめちゃくちゃ食っていたので、Manjaro 上ではずっと Firefox を使っていました。

でもそろそろコンソールを KVM スイッチで切り替えながら使うのも煩わしくなってきたので、もう一度使ってみようということでインストールしてみました。

まず、Manjaro では chrome-remote-desktop は AUR にあります。なので、Pamac(パッケージマネージャ GUI)で、AUR を有効にします。
当然ながら AUR は公式ではないので、何かあっても基本的には自己責任です。

AUR を有効にしたら、左側の「アップデート」をしてリポジトリを読み込み、「検索」で "chrome-remote-desktop" を検索します。
インストールが終わったら、Chromium を起動してブックマークバーのアプリアイコンを起動し、「Chromeリモートデスクトップ」を選択して PIN コードを取得、Windows 側に戻ってその PIN コードで接続します。

ちなみに上のスクリーンショットは GIMP で行いました。GIMP のスクリーンショットは、ショットボタンを押してから取り込みたいウィンドウをクリックして表に出し、指定秒数後に再度クリックすることで取り込むことができます。

さて、これだけだと毎回 PIN を入力しないと接続できません。そこでセッションを定義して常に接続可能なようにしておくと、いつでも Windows から接続が可能になります。
Chrome リモート デスクトップを使って他のパソコンにアクセスするの Linux のところの「ステップ3」、AUR の Package Details: chrome-remote-desktop のコメント、および Stack Exchange の Configuring Chrome Remote Desktop with Ubuntu Gnome 14.04 を参考にします。
  1. まず、/usr/share/xsessions/ にある *.desktop というファイルを確認します。うちの Manjaro は XFCE4 を使っているので、xfce.desktop というファイルがあります。
  2. xfce.desktop の中身を確認すると、最後のところに
    Exec=startxfce4
    Icon=
    Type=Application
    DesktopNames=XFCE
    という部分があります。この Exec で実行されているのがセッションです。
  3. ホームディレクトリに、.chrome-remote-desktop-session というファイルを作成します。ファイルの内容は、
    exec /usr/bin/startxfce4
    です。
  4. /opt/google/chrome-remote-desktop/chrome-remote-desktop ファイルを編集します。念のためオリジナルは cp chrome-remote-desktop chrome-remote-desktop.original とでもして保存しておきます。
    % diff -rub chrome-remote-desktop.original chrome-remote-desktop
    --- chrome-remote-desktop.original      2019-04-19 18:30:39.726890222 +0900
    +++ chrome-remote-desktop       2019-04-19 18:30:59.576888872 +0900
    @@ -75,11 +75,12 @@
     # with large or multiple monitors. This is a comma-separated list of
     # resolutions that will be made available if the X server supports RANDR. These
     # defaults can be overridden in ~/.profile.
    -DEFAULT_SIZES = "1600x1200,3840x2560"
    +#DEFAULT_SIZES = "1600x1200,3840x2560"
    +DEFAULT_SIZES = "1920x1080"
    
     # If RANDR is not available, use a smaller default size. Only a single
     # resolution is supported in this case.
    -DEFAULT_SIZE_NO_RANDR = "1600x1200"
    +DEFAULT_SIZE_NO_RANDR = "1920x1080"
    
     SCRIPT_PATH = os.path.abspath(sys.argv[0])
     SCRIPT_DIR = os.path.dirname(SCRIPT_PATH)
    @@ -101,7 +102,7 @@
     SYSTEM_SESSION_FILE_PATH = "/etc/chrome-remote-desktop-session"
    
     X_LOCK_FILE_TEMPLATE = "/tmp/.X%d-lock"
    -FIRST_X_DISPLAY_NUMBER = 20
    +FIRST_X_DISPLAY_NUMBER = 0
    
     # Amount of time to wait between relaunching processes.
     SHORT_BACKOFF_TIME = 5
    @@ -720,8 +721,8 @@
         self._init_child_env()
         self._setup_pulseaudio()
         self._setup_gnubby()
    -    self._launch_x_server(x_args)
    -    self._launch_x_session()
    +    #self._launch_x_server(x_args)
    +    #self._launch_x_session()
         display = self.get_unused_display_number()
         self.child_env["DISPLAY"] = ":%d" % display
    
  5. /etc/pam.d/chrome-remote-desktop というファイルを作成し、以下の内容を追加します。うちの場合、これがないと認証ができなくて chrome-remote-desktop がすぐに終了してしまいます。
    auth        required    pam_unix.so
    account     required    pam_unix.so
    password    required    pam_unix.so
    session     required    pam_unix.so
    
    ちなみにその時のエラーメッセージはこんな感じでした。
    % crd --restart
    The daemon is not currently running
    [0419/174820.966447:INFO:remoting_user_session.cc(691)] Daemon process started in the background, logging to
    [0419/174820.968761:WARNING:remoting_user_session.cc(613)] Failed to read from message pipe. Please check log
    
    Log file: /tmp/chrome_remote_desktop_20190419_174820_pXzIoB
  6. 終わったらファイルを保存して、systemctl --user enable chrome-remote-desktop します。また、% crd --start (あるいは systemctl --user start chrome-remote-desktop)もしておきます。
  7. chrome から「アプリ」→「Chrome リモートデスクトップ」をクリックし、一番下に追加された「リモート接続を有効にする」をクリックして、PIN コードを設定します。
  8. 他のパソコンから Chrome リモートデスクトップでこのパソコンを選択して、設定した PIN コードを入力します。
以上で常時接続可能になります。

Docker関連の情報集め。

なんでクジラ?

Docker Desktop for Windows のアイコンはクジラですが、なんでクジラなんだろうと考えていました。
仮想マシンのイメージは C:\Users\Public\Documents\Hyper-V\Virtual hard disks にありますが、そのファイル名は MobyLinuxVM.vhdx です。VHD(Virtual Hard Disk)はもともと Windows XP 以降で一部のエディションに組み込まれていた Virtual PC が使用していた形式で、VHDX 形式はジャーナリングによって耐障害性をあげたり最大容量を増やしたりしたもののようです。

仮想マシンのファイル名が MobyLinuxVM ということで、クジラのアイコンは Moby 繋がりなんでしょうか。でも Moby-Dick は白いマッコウクジラですし、そこらへんどうなんでしょうか。ちなみにこのアイコンのモデルは "Moby Dock" という名前だそうです。CALL ME MOBY DOCK。Moby Dock が背中に載せているのはコンテナなので、Docker の構造を表しているようですね。

余談ですが、mobylinux を mobilinux(moblin)と勘違いして、そういえばこれって MontaVista がやってたんじゃなかったっけ?といろいろ調べて、結構時間を無駄にしてしまいました。ガラケー時代に NEC なんかと組んでましたね、MontaVista。

VHDXファイルの容量は小さくできない?

さて、いろいろイメージを pull してコンテナ作って、なんてやっていると VHDX ファイルがどんどん大きくなっていきます。家では ArchLinux 入れてちょっといじっただけで 1GB 超えました。もっとも、VirtualBox でManjaroLinux で遊んでたら、そちらは 21GB を超えているのでたいしたことないとも言えますが、C:ドライブは SSD なのであまり大きくなるようだと困ります。

次のやり方で圧縮できました。あらかじめ pull していたイメージとコンテナは全部削除しています。
  • まず、「Hyper-V マネージャー」で "MobyLinuxVM" を「停止」します。
  • 次に Windows PowerShell を管理者モードで開きます。
  • PS C:\WINDOWS\system32> cd "C:\Users\Public\Documents\Hyper-V\Virtual hard disks"
    PS C:\Users\Public\Documents\Hyper-V\Virtual hard disks> Optimize-VHD -path .\MobyLinuxVM.vhdx -Mode Full
  • これで圧縮(というか未使用領域の開放)が始まり、だいたい 613MB まで縮まりました。もしかしたらこれが最小サイズかもしれません。

コンテナを間違ってたくさん作っちゃったんだけど

start / stop じゃなくて run を使うと新しいコンテナができてしまいます。コンテナが増えると VHDX ファイルのサイズも増えます。なのでコンテナの状況をひと目で分かるようになると便利です。
これを行うのが Kitematic という GUI アプリのようです。ただ、このページにはちょっと気になることが。
Legacy desktop solution. Kitematic is a legacy solution, bundled with Docker Toolbox. We recommend updating to Docker Desktop for Mac or Docker Desktop for Windows if your system meets the requirements for one of those applications.
legacy という単語は、こういうコンテキストで使われたときには「時代遅れ」とか「過去の遺物」というニュアンスがあって、システム要件が合うなら Docker Desktop をおすすめします、とのことです。Kitematic の代わりとなるものは示唆されていませんが。

Kinematic はここからダウンロードするか、タスクバーの Docker アイコンを右クリックして出るメニューから "Kitematic" を選択すると ZIP ファイルをダウンロードします。
早速 ZIP を展開して、出てきた Kitematic.exe を実行してみましたが、どうやらコンテナが起動していないとダメっぽいです。ということでペンディング。

アプリの導入前に構築できるか試したい

それこそ仮想環境の出番ですね。今回も uWSGI が Windows をサポートしないことに気づいたというきっかけがあっていじり始めてますし。

随時思いついたら追加していきます。

ところで、Docker をいじったきっかけは uWSGI なんですが、もしも Docker を使うとして、どういう構成がいいかを考えていました。
まず、データベースはメンテナンスを考慮すると、ホスト側にインストールするしかないでしょう。

ローカルのほうが最新ですの警告。

ManjaroLinux でパッケージマネージャを使っていると、しばらく前から「ローカルの xx のほうが最新です」の警告が出るようになりました。

気になったので調べてみたら、pacman -Syuu して該当パッケージをダウングレードするといいらしいです。
問題のパッケージは mesa 関連で、バージョン番号の付け方がそのパッケージだけ変更されていて、それでコンフリクトが起きたのかなと思いますが、これででなくなりました。

ボリュームコントロール+がバージョンアップしてアラームが鳴らなくなった件。

ボリュームコントロール+(旧Persist+)がバージョンアップして、たぶんこれまでは Android 8(Oreo)の上でちゃんとバックグラウンド動作してなかったんじゃないかと思いますが、逆にそれがちゃんと動作するようになって、夜間設定とぶつかっているのか、アラームが鳴らなくなりました。4月14日に更新されたようですが、新機能の説明が次のようになっています。
  • Fixed a bug with preset schedulers on some devices
  • Added the ability to take the device out of Do Not Disturb mode when changing the volume
  • Added instructions to hide the persistent "Volume Control is running" notification. The notification was added to keep the app running reliably in the background, but it can be hidden on Android 8.0 (Oreo) and above.
いくつかのデバイスでプリセットスケジュールのバグがあったのを修正した、ボリューム変更時に "Do Not Disturb" モードから抜け出す機能を追加した、永続的な「ボリュームコントロールが動作しています」通知を隠す方法を追加した。通知はアプリをバックグラウンドでしっかりと動作するようにキープするために追加されたが、Android 8.0 以降では隠せるようにした。

やっぱりここらへんが怪しいです。また、時計アプリとして HTC のものと Google のものと2つあるのも混乱の元かもしれません。
ともあれ目覚ましが鳴らないのはいただけないので、ちょっと設定を変更しながらチェックです。

Docker Desktop for Windowsを使ってみる。

Docker Desktop for Windows を使ってみます。
ダウンロードは Docker Desktop for Windowsのページからできますが、まずユーザ登録が必要です。
Docker Desktop for Windows is Docker designed to run on Windows 10. It is a native Windows application that provides an easy-to-use development environment for building, shipping, and running dockerized apps. Docker Desktop for Windows uses Windows-native Hyper-V virtualization and networking and is the fastest and most reliable way to develop Docker apps on Windows. Docker Desktop for Windows supports running both Linux and Windows Docker containers.
Docker Desktop for Windows は Windows 10 で動作するように設計された Docker です。ネイティブな Windows アプリケーションで、ドッカライズされたアプリをビルド、シップ、起動するための簡単に使える開発環境です。Docker Desktop for Windows は Windows のネイティブ Hyper-V 仮想化およびネットワーキングを利用していて、Windows 上での Dockerアプリを開発する最も速く信頼性の高い方法です。Docker Desktop for Windows は Linux と Windows 両方の Docker コンテナをサポートします。

Docker には2種類あるようで、Stable channel は4ヶ月毎の更新で、使用統計データを Docker に送るか送らないかを選べます。Edge channel は不安定なこともあるかもしれないけれど頻繁にバグ修正などが行われますが、使用統計データを Docker に送ります。
試しに使ってみるだけなので、ここでは Stable channel を選びます。
インストールが終わるとログアウトを求められます。ここでは再起動までは不要のようです。
再度ログオンすると、次のようなダイアログが表示されます。
「Hyper-V を有効化するけどいいですか?自動的に再起動しますけど。あと VirtualBox は動かなくなりますけど」とのこと。ここは「OK」します。
当然、自動的に再起動します。おそらく Windows コンポーネントの Hyper-V を有効にしてるんでしょう。
確認したらやっぱりそうでした。
デスクトップに "Docker Desktop" アイコンができています。
なんかクジラが荷物運んでます。
が、クジラをクリックしても何も起こらないので、まずは初心に戻って Get started with Docker for Windowsを読んでみます。
Docker is a full development platform for creating containerized apps, and Docker Desktop for Windows is the best way to get started with Docker on Windows.
Docker はコンテナ化されたアプリを作成するフル開発プラットフォームで、Docker Desktop for Windows は Windows 上で Docker を始める上でベストな方法です。
だそうです。

それでは早速コマンドプロンプトを起動して、docker --version を入力します。
$ docker --version
Docker version 18.09.2, build 6247962
次に、hello-world を pull します。
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:92695bc579f31df7a63da6922075d0666e565ceccad16b59c3374d2cf4e8e50e
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
pull だというのにコマンドは run のようですが、Docker Hub からなにやらダウンロードしてきました。
再度 dcoker run hello-world すると、上のメッセージの "Hello from Docker!" 以降が表示されました。どうやらそれがアプリの実行結果のようです。でもカレントディレクトリには hello-world はありません。

ちょっとディレクトリを調べてみると、%USERPROFILE%\AppData\Local\Docker にログファイルが、%USERPROFILE%\AppData\Roaming\Docker にはいくつかの .json ファイルがあります。また、\ProgramData\DockerDesktopにもファイルがあります。が、どうにも hello-world は見つかりません。

検索してみると、Forum に回答がありました。
C:\Users\Public\Documents\Hyper-V\Virtual hard disks に保存されているとのことです。
このイメージの保存場所を変更するには、「Hyper-V マネージャー」から行うのがよいようですが、とりあえずおいておきます。

Docker Hub を検索したら、ArchLinux があったので、これを使ってみます。
$ docker run archlinux/base
Unable to find image 'archlinux/base:latest' locally
latest: Pulling from archlinux/base
f3e37ac93b0e: Pull complete
Digest: sha256:f9496957524a239cf60cd0adb0a84ae633c0b712364988cd113e4fc66cdb8b7e
Status: Downloaded newer image for archlinux/base:latest

$ docker run archlinux/base
…何も起こりません。実はどうやらこれだけだと、仮想環境を起動してすぐに終わっている、ようです。以下のようにすることで、/bin/bash が起動します。
$ docker run -it archlinux/base /bin/bash
[root@95b5542f9322 /]# uname -a
Linux 95b5542f9322 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 GNU/Linux
ここで pacman を使ってみると、ちゃんと使えました。
さらに Get started with Docker for Windows に沿って進めると、今度は Nginx を走らせようとしています。
$ docker run --detach --publish 80:80 --name webserver nginx
docker run --help すると、--detach は「コンテナをバックグラウンドで走らせ、IDを表示する」、--publish 80:80 は「指定されたポートをホストに開放する」、--name webserver は「コンテナに名前をつける」だそうです。
対象的に、--attach というオプションがあって、これは STDIN/STDOUT/STDERR をコンテナにアタッチするという指示のようですから、--detach はその逆かもしれません。--publish の "80:80" は、コンテナ内のポート 80 をコンテナ外のポート 80 と接続する、というイメージです。
--name webserver で "webserver" という名前をつけていますが、これはコンテナを停止するときに利用できます。docker container stop webserver でバッググラウンドの Nginx が止まります。
また、コンテナの削除は docker container rm webserver で "webserver" コンテナが削除されます。ただしイメージ "nginx" は残ります。イメージを削除するのは docker rmi nginx です。ただし、そのイメージを参照しているコンテナがあると削除できません。なので docker container ls --all で停止しているコンテナも含めてすべて確認します。
"run" コマンドではコンテナを新規に作成しますが、すでにあるコンテナを開始するには docker container start とします。必要に応じて "-i" (interactive)オプションを指定します。

以上を踏まえると、Windows 上では動作できない uWSGI などは、Docker 上の Linux で動作させてしまえば、あとは TCP ポートを開けてやることで通信できる、ということになります。ただ、設定ファイルなどはイメージ内にあるのでシームレスにアクセスできないという点は面倒そうです。逆にローカルドライブはコンテナ内の Linux からマウントすることでアクセスできるようです。

コンテナ内から Docker を proxy してホスト PC から外部にアクセスできるので、モデルとしては、
Nginx (Windows) <-> uWSGI (Docker) <-> MariaDB (Windows)
などということもできそうです。

が、冷静に考えると、uWSGI を動かすために数百 MB のディスク領域と大量のメモリが必要です。これは開発用とかテスト用ならまだしも、本番ということなら「なんで Linux でやらないの?」ということになりますね、確実に。しかもコンテナの中で変更されたファイルは、履歴管理がやっかいです。これは相当分が悪いと、少なくとも自分的には考えてしまいます。

uWSGIはWindowsをサポートしない件。

Supported Platforms/Systemsを見て絶望です。

以下、メモ。
Dockerというのは、「コンテナ型の仮想化環境を提供するしくみ」だそうで、ハイパーバイザ型の VMware やホスト型の VirtualBox よりも軽いらしい。
Docker Desktop for Windows を実行するには
  • Windows 10 64bitの Pro、Enterprise あるいは Education で、バージョン 1607 以降
  • BIOS での仮想化の有効化。これは Hyper-V とは違い、通常はデフォルトで有効化されている。
  • CPU SLAT(Second Level Address Translation)が利用可能なこと。Intel CPU では EPT(Extended Page Table)、AMD CPU では NPT(Nested Page Table)という。
  • 最低 4GB の RAM
が必要とのこと。

Hyper-V がない環境では、VirtualBox を利用する Docker Toolbox というのを利用することができるらしい。一方、Hyper-V を BIOS で有効にすると VirtualBox は実行できなくなる。どちらがいいかはアナタ次第ということらしい。

けっこう気になるので、そのうちやってみる。

Windows10でNginx+MariaDB+Wordpressをインストールする。補足

Windows10でNginx+MariaDB+Wordpressをインストールする。その3までで使った nginx.conf のディレクティブと変数をさらっとまとめておきます。

その3で示した nginx.conf で出てきた順番で書き記します。太字の部分はリンクから飛ぶ解説をしっかりと理解したほうがよさそうな項目です。順次説明を追加します。

ディレクティブ 使用コンテキスト 説明 リンク
worker_process main workerプロセスの数。
'auto' を指定すると、自動でコア数を検出して設定される。
リンク
error_log main, http, mail, stream, server, location
エラーログを書き出すファイルとレベルを設定する。
ファイル名の代わりに 'syslog:' を使用することもできる。
リンク
pid main メインプロセスのプロセスIDを記録しているファイルの指定。 リンク
events main 接続関連の設定を行うコンテキスト。 リンク
worker_connections events 同時接続数の設定。クライアントだけでなく、FastCGIなどへの接続も含まれる。 リンク
http main HTTPサーバ関連の設定を行うコンテキスト。 リンク
include どこでも 設定を記載したファイルを読み込むためのディレクティブ。 リンク
default_type http, server, location デフォルトのMIMEタイプを設定する。 リンク
sendfile http, server, location sendfile() の許可/拒否を指定する。 リンク
keepalive_timeout http, server, location keep-alive時間を指定する。 リンク
gzip http, server, location 応答のgzipの許可/拒否を指定する。 リンク
upstream http サーバのグループを定義する。UNIXドメインソケットとTCPの混在も可能。 リンク
server http 仮想サーバの設定を行うためのディレクティブ。 リンク
listen server IPの場合にはアドレスとポート、あるいはUNIXドメインソケットの場合にはファイル名を指定する。 リンク
server_name server 仮想サーバの名前を指定する。スペースで区切って複数を併記可能。また '*' も使用可能。 リンク
root http, server, location リクエストに対するルートディレクトリを指定する。 リンク
location server, location リクエストURIに関連した設定を行う。 リンク

Windows10でNginx+MariaDB+Wordpressをインストールする。その3

Windows10でNginx+MariaDB+Wordpressをインストールする。その2の続きです。

Nginx を WordPress 用に設定する

PHP の動作が確認できたら、早速 WordPress 用の設定に移ります。WordPressを参照します。
このページの Abridged basic setup では、upstream コンテキストを利用しています。
# Upstream to abstract backend connection(s) for php
    upstream php {
            server unix:/tmp/php-cgi.socket;
            server 127.0.0.1:9000;
    }
upstream はhttpコンテキストの中で使用され、fastcgi_pass や uwsgi_pass から参照できるバックエンドを提供します。上記の場合には、fastcgi_pass php;という形で参照することができます。

これを利用して WordPress 用の設定を nginx.conf に追加します。
location /blog {
    root c:\srv\www\blog;
    try_files $uri $uri/ index.php?$args;
}
設定を変更したら、nginx -s reload して新しい設定を読み込ませます。ここで何らかのエラーがあれば、それに応じて設定を修正します。

上記のディレクティブは、http://localhost/blog 以下のアクセスは実際のファイルシステム上は c:\srv\www\blog 以下にあるのでそこをルートとして参照する、という内容です。try_files は、URL が '/' で終わっていないけれどディレクトリ名で終わっていた場合に、末尾に '/' をつけてファイル名を補完して試す、というディレクティブです。

最終的に nginx.conf は以下のようになりました。コメントなどは省いています。
# vim:fenc=utf-8 ff=unix ts=4 sw=4 sts=4 si et fdm fdl=99 tw=72:

worker_processes  1;
error_log  logs/error.log;
pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    gzip  on;

    # upstream for php-cgi
    upstream php {
        server 127.0.0.1:9123;
    }

    server {
        listen       80;
        server_name  localhost;
        root   c:\srv\www;

        location / {
            index  index.html index.htm index.php;
            try_files $uri $uri/ /index.php?$args;
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location /blog {
            root c:\srv\www\blog;
            fastcgi_split_path_info ^(/blog)(/.*)$;
            try_files $uri $uri/ /blog/index.php?$args;
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9123
        #
        location ~ \.php$ {
            include        fastcgi.conf;
            fastcgi_intercept_errors on;
            fastcgi_pass   php;
        }
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            expires max;
            log_not_found on;
        }
    }
}
サーバのドキュメントルートを c:\srv\www に設定していますので、 c:\Apps\Nginx\html にはアクセスしなくなります。
逆に、こうしないと c:\Apps\Nginx\html をドキュメントルートとしてファイルを探していたようで、ちゃんと動きませんでした。

nginx.conf を変更したら、nginx -s reload でリロードします。ただ、これは c:\Apps\Nginx ディレクトリでやらないとエラーになるようです。reload したら http://localhost/blog/wp-admin/install.php にアクセスします。
ちゃんとアクセスできました。ところで、WordPress用のデータベースはまだ作成していません。早速作ります。

MariaDBにWordPress用データベースを用意する

MariaDB をインストールした際に、GUI フロントエンドの HeidiSQL もインストールされていると思いますので、これを起動して、ローカルホストの MariaDB に接続します。
左側のデータベースとテーブルが表示されているペインで右クリックをし「新規作成」→「データベース」を実行します。
ここでは "wp_database" という名前のデータベースを作成します。
次にユーザを作成し、アクセス権を設定します。HeidiSQL のユーザのアイコンをクリックして「ユーザーマネージャー」を開きます。
アカウントの追加ボタンを押し、ユーザ名、ホスト名、パスワードを入力して、さらに「オブジェクトの追加」を押します。オブジェクトとしていま作成した "wp_database" を追加し、すべての権限を付与します。
これでデータベースの準備はできましたので、WEBブラウザに戻って先に進みます。
今作成したデータベース名などを入力して、「送信」ボタンを押します。するとエラーが出ました。

Nginx のエラーログを参照すると、次のようなエラーが記録されていました。
2019/04/13 10:54:26 [error] 15768#10284: *55 FastCGI sent in stderr: "PHP Fatal error:  Uncaught Error: Call to undefined function mysql_connect() in C:\srv\www\blog\wp-includes\wp-db.php:1645
Stack trace:
#0 C:\srv\www\blog\wp-admin\setup-config.php(305): wpdb->db_connect()
#1 {main}
  thrown in C:\srv\www\blog\wp-includes\wp-db.php on line 1645" while reading response header from upstream, client: 127.0.0.1, server: localhost, request: "POST /blog/wp-admin/setup-config.php?step=2 HTTP/1.1", upstream: "fastcgi://127.0.0.1:9123", host: "localhost", referrer: "http://localhost/blog/wp-admin/setup-config.php?step=1&language=ja"
スタックトレースを見ると、データベースへの接続で失敗しているようです。このようなときにまず疑うのは php.ini です。確認してみたところ、 "Extension" 節で mysqli と pdo_mysql がコメントアウトされ、mysql が有効になっていました。途中で別の PC で作業を続けたのがいけなかったようです。
これを修正して、mysqli と pdo_mysql(実際には mysqli を使用している様子)を有効にして、php-cgi.exe を再起動すると、ちゃんと次に進みました。
次のページでは、サイト名、ユーザ名、メールアドレスなどを入力します。
次に進むと、背後で MariaDB のデータベースに適切にテーブルを作成し、WordPress のインストールが終わります。
ちゃんとアクセスできて、テーマも Twenty Seventeen に変更できました。

Windows10でNginx+MariaDB+Wordpressをインストールする。その2

Windows10でNginx+MariaDB+Wordpressをインストールする。その1の続きです。

Nginxの設定

Nginx の設定は、c:\Apps\Nginx\conf\nginx.conf で行います。Windows 版の PHP は php-fpm を持っていないため、FastCGI で行うことになります。

余談ですが、Nginx の配布物には nginx.vim というシンタックスハイライタが含まれていますが、これは Mercurial で運用されている Nginx のリポジトリにあるので、dein.vim でインストールすることは無理っぽいです。GitHub にもリポジトリのミラー(?)はあるのですが、階層の中(https://github.com/nginx/nginx/tree/master/contrib/vim)にあるので多分無理なのかなと思います。(それとも repo="nginx/nginx/contrib/vim" とかできるのかな?)
またそれとは別に chr4/nginx.vim というのもあるようです。dein.vim で使うならこちらのほうがいいかもしれません。うちではこれを使うことにしました。

WordPress 用の Nginx の設定ですが、Nginx サイトの WordPress と、PHP FastCGI Example および PHP FastCGI on Windows のページを参考にします。

まずざっと Nginx の設定ファイルの構造をおさらいします。
設定ファイルはディレクティブとそのパラメータから成り立っていて、さらにいくつかのディレクティブはコンテナ('{}'で囲まれたもの、ブロックとも)構造を持ちます。
また特定の機能に関する設定のみを記載したものを取り込む include ディレクティブもあります。

トップレベルディレクティブには、events、http、mail および stream があって、トラフィックのタイプによってまとめられています。これらをコンテキストといいます。これらのコンテキスト以外の部分は main コンテキストと呼ばれます。
トラフィックを扱うコンテキストでは、仮想サーバを構成するために一つ以上の server ブロックを持ちます。server ブロックで使用するディレクティブはトラフィックのタイプによって異なります。
HTTP トラフィック(http コンテキスト)では、server ディレクティブはドメインあるいは IP アドレスに対して処理内容を定義するのに使用されます。server ブロックには1つ以上の location ブロックがあり、URI の処理方法を指定します。構造的には以下のようになります。
http {
        server {
            location {}
            location {}
        }
        server {
            location {}
            location {}
        }
    }
また、ドキュメントルートは location ブロックごとに指定できます。したがって、たとえば
http {
        server {
            server_name  www.foobar.com;
            location /wiki {
                root c:/srv/www/moinmoin;
            }
            location /blog {
                root c:/srv/www/wordpress;
            }
        }
    }
というような設定ができることになります。余談ですが、MoinMoin は Python で書かれた WikiEngine です。

それを踏まえた上で、Nginx の conf ディレクトリを眺めていきます。
まずは nginx.conf で、これが設定ファイルの本体になります。その他のファイルは機能ごとに設定をまとめたファイルで、この nginx.conf からインクルードします。

今回は FastCGI で動かしていくのですが、まず目につくのは fastcgi.conffastcgi_params という同じようなファイルが並んでいるところです。この2つの違いは、
fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
という行が fastcgi.conf には追加されているというだけで、あとは全く同じです。

PHP-FastCGI on Windowsを見ると、
root c:/www;

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9123;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
となっていますので、これをベースにします。

SCRIPT_FILENAME のところは同じ構文なので、そのあとの include ディレクティブでは fastcgi.conf を読み込んでもよいことがわかります。

nginx.conf の中で、"Pass PHP scripts to FastCGI server listening..." のところを以下のようにします。
location ~ \.php$ {
        root           c:\srv\www;
        fastcgi_index  index.php;
        fastcgi_pass   127.0.0.1:9123;
        include        fastcgi.conf;
    }
これでファイルを保存して nginx.exe を起動します。


ちょっとここで問題発生。ポート80が使用中で Nginx がエラーを出します。
コマンドプロンプトから nginx.exe を実行すると、
[emerg] 6952#6692: bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions)というエラーが出て、Nginx が 80 ポートを開くことができない状態でした。
そこで、netstat -ano | more してみると、
TCP         0.0.0.0:80             0.0.0.0:0              LISTENING       4
という行を見つけました。PID 4 のプロセスがポート 80 を使用中のようです。
この場合、回避策は二通りで、ポート 80 を開放させるか、Nginx のポートを(たとえば 88 などに)移動するか、です。
もうちょっと調べてみると、この PID 4 は "System" となっていて、System が開いているのはわかったけれどそれを利用している実態がわかりません。まさか IIS は動かしてないし…と思ってタスクマネージャーを開いてみると、
「World Wide Web 発行サービス」というのが見つかりました。こいつが犯人か。
「サービス」から探してみると、
自動起動で実行中。これを「サービス」から開いて、「停止」して「無効」にしておきます。この状態で試してみると Nginx が起動できるようになりました。
「タスクマネージャー」のほうには、「Windows プロセス アクティブ化サービス」というのもありますが、これは MSMQ や PIPE などの他のサービスにも影響するようなので、とりあえず放っておきます。

次に FastCGI で Nginx が接続するプログラムを起動します。これには PHP と一緒にインストールされている php-cgi.exe を使用します。
php-cgi.exe -b 127.0.0.1:9123
として、ポート 9123 で待ち受けます。

ここまでやったら、index.php ファイルを用意します。
この1行だけのファイルを作成して、c:\srv\www に index.php のファイル名で保存します。

そうしたらWEBブラウザを立ち上げ、http://localhost/index.php にアクセスします。
ちゃんと動いていれば、PHP に関する情報一覧が表示されます。

このとき、バックグラウンドでの動作は、次のようになっています。
  1. WEBブラウザがローカルホストのポート 80 に /index.php をリクエストする
  2. Nginx がポート 80 でリクエストを受け取る
  3. URL のエクステンションが php なので、fastcgi_pass で指定されたパスに c:\srv\www\index.php をリクエストとして転送する
  4. ポート 9123 で待ち受けていた php-cgi.exe が index.php を実行してその結果を Nginx に返す
  5. Nginx が WEBブラウザに応答する
ともあれこれで一応 Nginx から PHP を FastCGI 経由で動作させることができました。
Windows10でNginx+MariaDB+Wordpressをインストールする。その3に続きます。

Windows10でNginx+MariaDB+Wordpressをインストールする。その1

以前にも書いたのですが、Nginx の設定がうまくいかずに途中でちょっと投げ出していたので、ちゃんと最後まで書きました。

まず前知識として、WordPress は Apache で運用することを前提としています。そのため、Apache と組み合わせるためのモジュールなども充実していますし、Apache + PHP でのキャッシュ機構などを利用することでパフォーマンスも得ることができます。
何らかの理由で Nginx であることが必要な場合以外には、基本的には Apache を使ったほうがいいでしょう。
あるいは、外部へのインタフェースは Apache に任せて、WordPress も Apache で運用し、Nginx が必要な部分は Apache に proxy (あるいはredirect)させるという方法も考えられます。Nginx 一本で行くんだ!という縛りがないなら検討してみるのも無駄ではないでしょう。

MariaDBのインストール

MariaDB.orgから Download へと進んで、 MariaDB の MSI ファイルをダウンロードします。
2019年4月10日現在の stable は 10.3.14 です。ダウンロードしたら、MSI を実行します。
GPL のライセンス同意をして、インストールする機能については特に好みがなければそのまま "Next" を押し、root パスワードを設定します。
ここではサーバの文字エンコーディングを UTF-8 にします。そのほうが何かと都合がよいので。
次のサービス名とポート番号などはそのままにします。

利用統計を送るかどうかはお好みで。ここではプライベートなサーバなので送らないようにします。
インストールが終わるとデスクトップに HeidiSQL のアイコンが作られます。またWindowsサービスとして登録され、バックグラウンドで自動実行されていますので、そのまま利用できます。

とりあえずここでは HeidiSQL にセッションを作成して保存するところまでやっておきます。
HeidiSQLを起動すると以下のような GUI 画面が出てきます。
左下の「新規」→「セッションを追加」をクリックし、セッションの設定画面を開きます。
先程設定した root パスワードを入力して「開く」をクリックするとセッションが張られます。
MariaDB のインストールは以上です。

Nginxのインストール

次に Nginx (エンジンX)のインストールです。"download" リンクから "Stable version" の "nginx/Windows-x.xx.x" の ZIP ファイルをダウンロードします。
現在のバージョンは 1.14.2 です。

ダウンロードした ZIP ファイルを展開すると、そのままインストールイメージになるので、適当なところに配置します。
ここでは C:\Apps\Nginx に展開した中身(nginx.exe とか conf とか)を移動します。あとで便利なように、デスクトップに nginx.exe のショートカットも作成しておきます。

Nginx のインストールは以上です。

PHPのインストール

次は PHP のインストールです。PHP.netから "Downloads" に飛んで、特にバージョンにこだわりがなければ最新の stable である 7.3.4 の "Windows downloads" から "VC15 x64 Non Thread Safe" をダウンロードします。

ZIP ファイルを展開すると、これもそのままインストールイメージになっているので、適当なところに配置します。
ここでは Nginx と同様に C:\Apps\PHP にします。
ファイルの中身を移動したら、PHP.INI ファイルを設定しますが、アーカイブに "php.ini-development" と "php.ini-production" のファイルが含まれています。どちらでもいいのですが、ここでは開発をするわけではないので、一旦 "php.ini-production" を "php.ini" にコピーします。
コピーしたらエディタで開いて、いくつかの項目を編集する必要があります。

extension_dir = "c:\Apps\PHP\ext"
upload_max_filesize = 1G
extension=curl
extension=gd2
extension=gettext
extension=intl
extension=mbstring
extension=exif ; Must be after mbstring as it depends on it
extension=mysqli
extension=openssl
extension=pdo_mysql

"extension_dir" は、PHP を C:\PHP にインストールした場合には不要です。
最後の2つはちょっと微妙で、WordPress が DBサーバに接続するときにどちらのドライバを使うかという選択です。PDO というのは PHP Data Object の頭文字で、PHP としてはこちらに移行していきたいような感じですが、実際のところはアプリケーションがどちらを利用するかを決定するので、必要に応じてどちらか一方あるいは両方を有効にしておく必要があります。
PHP の以前のバージョンから php.ini の書き方が変わってきていて、Windows 版のときには extension 名に .dll を付けていたのが、現在は不要になっています。互換性のために .dll がついていても動作するようですが、将来的には .dll は deprecate になるようです。
また、ShiftJIS などで使用する場合には、
zend.multibyte = on
にする必要があります。

それから、ext ディレクトリには nghttp2.dll というのがあり、これは Nghttp2: HTTP/2 C Library だと思いますが、php.ini には特に設定項目もないようで、Nginx が独自に HTTP/2 をインプリメントしていることを考えると、おそらくは Apache 用モジュールではないかと思います。

インストールが終わったら、PHP にパスを通しておきます。

WordPressのインストール

最後に WordPress のインストールです。現在のバージョンは 5.1.1 です。
ダウンロードしたら、ZIP ファイルを展開して適当なところに配置します。ここでは、C:\srv\www\blog 以下に配置することにします。
Windows10でNginx+MariaDB+Wordpressをインストールする。その2に続きます。

TeXの処理系の表記。

Mathjax で \(\rm \TeX\) の表記を行うには、インラインの場合には
\(\rm \TeX\)
と、また独立させたい場合には
$$\rm \TeX{}$$
などと表記します。

じゃあその他の\(\rm TeX\)処理系はどこまで使えるんだろうということで、やってみます。

$$\rm \TeX{}, \LaTeX{}, \XeTeX{}, \pTeX{}, \MikTeX{}, \LuaTeX{}, \BibTeX{} $$

どうもダメみたいですね。

それから LaTeX で使用できるシンボル(文字記号)の一覧を見つけたのでついでに。
The Comprehensive LATEX Symbol List

manpageファイルからpdfを作る。

ちょっと検索したけどそれっぽいのが見つからなかったので自分用メモ。

manpageファイル(cat.1とか)を\(\rm \TeX\) でタイプセットできたよな、と思ったけれどちょっと勘違いで、groff で dvi 形式で出力してから dvi を PDF に変換していたのでした。

cat.1 の場合には、
$ groff -mandoc -Tdvi cat.1 > cat.dvi
$ dvipdfmx cat.dvi
で cat.pdf ができました。

当然ながら groff は pacman -S msys/groff でインストールし、dvipdfmx は TeXLive のものを使っています。

ふと texinfo形式なんてのもあったなぁと思い出して調べてみたら、GNU Texinfoはまだ健在で、newstexinfo - GNU documentation system - News: Texinfo 6.6 releasedによれば2019年2月17日に Texinfo 6.6 がリリースされたようです。なんでも2016年の6.3(6.2が出たけどバグで6.2は抹消されたみたいです)から UTF-8 に対応して、日本語も扱えるようになったっぽいです。
Texinfoファイルから、GNU Texinfo を使って日本語 PDF を生成するあたりのお話は、TrueRoad's Web Pageさんの本家 Texinfo に取り込まれましたあたりにあります。\(\rm Lua\TeX\)または\(\rm Xe\TeX\)が必要で、同時に texinfo も必要とのこと。MSYS2 の texinfo は 6.5 ですね。

texinfo といえば、Emacs をビルドするときに info形式にコンパイルする作業がありましたが、今でもEmacs使っている人は、Emacs の info と互換のある info も使ってるんでしょうか。コンソールベースの人なら使うこともあるでしょうけど。

でも、自分が Linux 使い始めた頃は「Linuxはインストールが終わったら次にやることはカーネルのtarball拾ってきてコンフィグしてビルド」という世代だったので、とにかくコンソール、X なんかインストール直後で起動すればラッキーくらいだったのだけれど、時代も変わって LKM とかによるモジュラー構造になって、モノリシックなカーネルというのは一部組込系以外では残らないのですかね。

MultitailをWindows上で動かす。

Nginx を動かす、というのをやっていて、でも access_log と error_log を同時に眺めたい、そういえば multitail ってのがあったな、と思いだして MSYS2 でパッケージないかしらと探したのですが、なかったので自分でビルドしましょうということです。

他にもあると思いますが、Multitail はこちらを参照しました。ソースは GitHub の flok99/multitail にあります。
必要要件として、ncurses ライブラリがあること、とのことですが、MSYS2 ではすでにインストールされていたので問題なしです(実は問題はありましたが)。

まず、gcc があるかどうかを確かめたところ、gcc は入っていませんでした。なので、pacman -S msys/gcc します。
次に make してみたら、ncursesw/panel.h: No such file or directory というエラーが出たので、pacman -S msys/ncurses-devel します。
いろいろと "警告" や "備考" というのが出てきましたが、それだけでビルドは終了し、試してみたらちゃんと動いたのでそのまま使ってみます。

設定などもあるみたいなので、そのへんはまた今度。

TortoiseHG+OpenSSHでBitbucketにssh接続する。

TortoiseHG を使って Bitbucket の Mercurial リポジトリに接続するときに、OpenSSH for Windows の ssh-keygen で作った Ed25519 のキーは扱えない、みたいです。

前提条件として、Bitbucket にアカウントとリポジトリを作成し、公開鍵も登録しておきます。秘密鍵じゃなくて公開鍵なので間違わないように。

さて、最新の TortoiseHG のバージョンは 4.9.0 です。

TortoiseHG は SSH 接続する際に、付属の TortoisePlink.exe を使います。これは PuTTY の Plink.exe をベースにしているらしいです。
見ての通り、バージョンは 0.68 です。
一方、PuTTY のほうは最新バージョンは 0.71 です。PuTTY のほうでも、一応 PuTTY wish ed25519 にあるように、Ed25519 はサポートしているようです。
ただ、秘密鍵を .PPK(PuTTY形式)にしないといけないようで、そのためには puttygen.exe が必要です。ということでこちらからダウンロードします。
0.68 の puttygen.exe は、あらかじめ秘密鍵のパスフレーズを抜いておかないとインポートできませんが、最新の 0.71 はそのままでインポートできます。パスフレーズを入力してから、"Save private key" で PuTTY形式の秘密鍵を作成します。

次に ~/mercurial.ini を編集します。
[ui]
ssh = "C:\Program Files\TortoiseHg\lib\TortoisePlink.exe" -ssh -i C:\Users\chiyosuke\.ssh\id_ed25519.ppk
こんな感じで定義します。
そうしたら、hg clone ssh://hg@bitbucket.org/chiyosuke/repos みたいな感じで使えます。

次にリポジトリを作成して clone します。
まず、Bitbucket の ダッシュボードを開きます。
"+" リンクをクリックして、"CREATE" → "リポジトリ" します。
下の方に "IMPORT" というのがあるのが気になります。これは他のホスティングサイトからリポジトリをインポートするための機能のようです。
さあ、空のリポジトリ(README.mdがあるかも)ができました。
次はこれをローカルに clone します。
まずコマンドプロンプトを起動してクローンしたい場所に移動します。
次に今 Bitbucket に作成したリポジトリを開きます。
この「クローンの作成」をクリックすると、Mercurial でクローンするためのコマンドを表示してくれますので、それをコピーし、コマンドプロンプトに貼り付けて実行します。

ローカルにクローンできたら、そのリポジトリのディレクトリを開いて、.hg/hcrc を編集します。以下は ~/.config をリポジトリに登録してクローンしたときの設定です。
--- C:/Users/chiyosuke/.config/.hg/hgrc~ Sun Apr  7 07:53:53 2019
+++ C:/Users/chiyosuke/.config/.hg/hgrc Sun Apr  7 08:42:07 2019
@@ -1,6 +1,8 @@
 # example repository config (see 'hg help config' for more info)
 [paths]
 default = ssh://hg@bitbucket.org/chiyosuke/.config
+default:pushurl = ssh://hg@bitbucket.org/chiyosuke/.config
+
 
 # path aliases to other clones of this repo in URLs or filesystem paths
 # (see 'hg help config.paths' for more info)
@@ -11,4 +13,22 @@
 
 [ui]
 # name and email (local to this repository, optional), e.g.
-# username = Jane Doe <jdoe@example.com>
+merge = winmergeu
+editor = nvim
+username = chiyosuke
+askusername = True
+ssh = "C:\Program Files\TortoiseHg\lib\TortoisePlink.exe" -ssh -i C:\Users\chiyosuke\.ssh\id_ed25519.ppk
+
+[tortoisehg]
+ui.language = ja
+vdiff = winmergeu
+editor = nvim
+shell = powershell
+summarylen = 80
+closeci = False
+confirmdeletefiles = True
+
+[extensions]
+win32mbcs = 
+mq = 
ここまでやったらあとは通常通り。ファイルを作成して、add して、commit して、push します。
TortoiseHG では push は Synchronize というメニューから呼び出されるので、push を探しても見つかりません。さらに Synchronize はリポジトリのトップディレクトリでしか現れませんので、ないよないよと探さないように。

一方、すでにローカルにあるリポジトリを Bitbucket に登録して使う方法です。Push versioned code to an empty repositoryの翻訳です。
---
存在するリポジトリを Bitbucket の空のプロジェクトにアップロードできます。こうすることで、Bitbucketはコミット履歴を管理するようになります。
もしまだ Bitbucket リポジトリを持っていないなら、最初に Bitbucket にリポジトリを作成してください。
  1. 最初の設定ファイルを編集します。
    (リポジトリ)/.hg/hgrc を開き、作成したリポジトリの「クローンの作成」で表示される URL をコピーして貼り付けます。
  2. コマンドプロンプトでローカルリポジトリのルートディレクトリに移動します。
  3. hg push します。
---
ということのようです。

LaTeXコマンドのあとには空白を入れる。

Neovim+vimtex+TeXLive2018でTeX環境を作ってみる。では、すでに ALE をインストールしていたので、自動的に chktex による構文チェックが走っていました。

chktex 自体は TeXLive 2018 に含まれているので、ALE がデフォルトで使用するようになっているようです。

で、\(\rm \LaTeX\) 文書中で \LaTeX と入力すると、Command terminated with space. (1) などというヒントが表示されました。エラーではないですが、\(\rm \LaTeX\)に関する記事などを書いているとそこらじゅうで出まくります。

ちなみに \(\rm \LaTeX\)は、Mathjax を使って部分的に\(\rm \LaTeX\)として処理させています。記法は、\(\rm \LaTeX\) という形で埋め込んでいます。

話を戻して、ALE (chktex)の警告の件ですが、\LaTeX␣ はコマンドとして解釈されるので、通常は地の文ではその次に空白が来ませんから、次の単語とくっつきます。\(\rm \TeX\)文書中で対処する場合には、\LaTeX␣\LaTeX\␣とします。日本語文書の場合でも末尾にスペースを入れて次の文字とは離します。
なので、
$$
\verb|\LaTeX is a typesetter.| \Longrightarrow {\rm \LaTeX is\ a\ typesetter.}\\
\verb|\LaTeX\ is a typesetter.| \Longrightarrow {\rm \LaTeX\ is\ a\ typesetter.}\\
\verb|\LaTeX\ は組版。| \Longrightarrow {\rm \LaTeX\ は組版。}
$$
となるため、やっぱり \(\rm \TeX\)文書中で対処すべきですね。

Neovim+vimtex+TeXLive2018でTeX環境を作ってみる。

以前に Neovim で \(\rm \LaTeX\) の環境構築をやって、Neovim では Vim にあった "--remote-*" コマンドラインオプションが削除されてしまったために、vimtex での inverse search ができずに挫折していました。
SyncTeX対応のPDFビューワ。でちょっと触れていますが、それを解決するために neovim-remote という Python モジュールを使って、Python インタフェース側から解決しましょうかというのがあったのですが、結局うまく行ってませんでした。

ぼちぼちあれから1年経つので、どうなってるのかな、と。もっとも Visual Studio Code + TeXLive でかなりいい感じの環境が手軽に構築できるので、あとは日本語入力のON/OFFをうまいことやってくれないかな、とかエディタ周りの使用感によって左右されるのかなとは思いますが。

まず、2019年4月5日現在、Neovim v0.4.0-529 には '--remote-*' 系オプションは実装されていないようです。これはすなわち、neovim-remote を使う必要がある、ということでしょう。現在の neovim-remote はバージョン 2.1.7 になっています。

'--remote-*' 系オプションに関する議論は、vimtex の Add support for neovim #262 あたりから始まって、neovim の restore --remote (+clientserver) #1750あたりに展開し、[WIP] Added clientserver --remote #8326あたりで作業に取り掛かっている方がいらっしゃるという状況です。

Neovim(というか nvim)は起動するとサーバソケット(Windowsの場合には名前付きパイプ)をオープンします。:echo v:servername
\\.\pipe\nvim-12345-0'
というような値を返してきます。

neovim-remote は、 'nvr' という実行形式ファイルを使って Neovimのサーバソケットと通信します。vimtex においてこの通信が本当に必要なのは、SyncTeX を利用するときだけです。Neovim から \(\rm \LaTeX\) を起動してコンパイルし、SumatraPDF で表示するだけならばぶっちゃけ不要です。
が、生成された PDF を見て、レイアウトがおかしかったりタイポがあったりしたときに、PDF の該当箇所をクリックすることで TeX 文書の該当箇所にジャンプしてくれる SyncTeX はとても便利です。

というような点を踏まえて、設定してみます。

まずは vimtex の wiki から Neovim のところに最初の設定が書いてあります。
let g:vimtex_compiler_progname = 'nvr'

次に vimtex の doc で、
let g:vimtex_view_general_viewer = 'SumatraPDF'
let g:vimtex_view_general_options
  \ = '-reuse-instance -forward-search @tex @line @pdf'
  \ . ' -inverse-search "gvim --servername ' . v:servername
  \ . ' --remote-send \"^^'
  \ . ':drop \%f^:\%l^:normal\! zzzv^'
  \ . ':execute ''drop '' . fnameescape(''\%f'')^'
  \ . ':\%l^:normal\! zzzv^'
  \ . ':call remote_foreground('''.v:servername.''')^^\""'

となっているところを参照します。これは inverse-search に関する設定で、SumatraPDF に渡すオプションです。逆に言えば、これを設定する前にコマンドプロンプトから SumatraPDF をオプション付きで起動して動作するかどうかを確かめることができます。

なので手順を踏んでやってみます。

まず、あらかじめ TeX ファイルをコンパイルして PDF と SyncTeXファイルを作っておきます。ページ数などがある程度あったほうがいいので、ちょっと長めのファイルを用意します。ここでは TeXLiveに含まれている pxchfon.tex を使います。このパッケージは日本語のフォントを変更するときに必ずお世話になるものですから、PDFを手元に用意しておくのも無駄にはなりませんし。

適当なディレクトリを用意して、pxchfon.tex をダウンロードします。ここでは手動で PDF を作成するので、コマンドプロンプトを開いてそのディレクトリに移動し、latexmk pxchfon と実行します。
pxchfon.tex は uplatex で組版するようになっていますから、必要があれば latexmkrc を別途作成しておきます。
ちなみにうちのは以下のような感じです。
$latex = 'uplatex %O -kanji=utf8 -no-guess-input-enc -synctex=1 -interaction=nonstopmode %S';
$pdflatex = 'pdflatex %O -synctex=1 -interaction=nonstopmode %S';
$lualatex = 'lualatex -cmdx %O -synctex=1 -interaction=nonstopmode %S';
$xelatex = 'xelatex %O -synctex=1 -interaction=nonstopmode %S';
$biber = 'biber %O --bblencoding=utf8 -u -U --output_safechars %B';
$bibtex = 'upbibtex %O %B';
$makeindex = 'upmendex %O -o %D %S';
$dvipdf = 'dvipdfmx %O -o %D %S';
$dvips = 'dvips %O -z -f %S | convbkmk -u > %D';
$ps2pdf = 'ps2pdf.exe %O %S %D';
$pdf_mode = 3;
$pdf_previewer = '"C:/Program Files/SumatraPDF/SumatraPDF.exe" -reuse-instance';

この内容を、%USERPROFILE%\.config\latexmk\latexmkrc に保存しておきます。正確に言えば、latexmk は XDG Base Directory に準拠していますので、$XDG_CONFIG_HOME/latexmk/latexmkrc ということになります。うちでは他のプログラムで参照するものもあるので、環境変数 XDG_CONFIG_HOME を %USERPROFILE%/.config に設定しています。

TeXLive が適切にインストールされて設定されていれば、上記の latexmk で pxchfon.pdf と pxchfon.synctex.gz ができているはずです。

次に、SumatraPDF にパスが通っているかを確認します。Neovim からビューワを起動するときに、パスが通っていないと起動できません。コマンドプロンプトで sumatrapdf pxchfon.pdf として起動します。
また、nvr にパスが通っているかどうかも確認します。コマンドプロンプトで nvr として確認します。パスが通っていなければ Python の Scripts にもパスを通します。

次に、Neovim で pxchfon.tex を開きます。SyncTex の動作確認だけですので vimtex は組み込んでいなくても構いません。

Neovim で :echo v:servername してパイプ名を調べます。ここでは \\.\pipe\nvim-15280-0 という名前が返ってきましたのでこれを控えておきます。

SumatraPDFのオプション設定で、逆順検索コマンドラインを設定します。逆順というよりも逆方向だとは思いますが。
nvr --servername \\.\pipe\nvim-15280-0 --remote-send "%lG"


ここまでやったら、PDFの適当なところでダブルクリックしてみます。
ジャンプしましたか? うちではちゃんとジャンプできました。え? ていうかほんとにジャンプできました。おお、すごい。

ということは、Neovim の vimtex から latexmk でコンパイルして、SumatraPDF で PDF 表示させて、PDF から SyncTeX でソースの該当箇所に飛ぶことができるということですね。

ちなみに上記の nvr でパイプに送りつけているコマンドは、%lG (%l はダブルクリックした箇所の行番号で、Gコマンドで%l行に移動する、というだけ)です。

ということなので、あとは適切に .toml を書いておけばOKとなります。
[[plugins]]
# vimtex: LaTeX documentation support plugin
repo = 'lervag/vimtex'
depends = ['deoplete.nvim']
on_ft = 'tex'
hook_source='''
  if filereadable(expand('~/.config/nvim/vimtex-local.vim'))
    source ~/.config/nvim/vimtex-local.vim
  endif
'''
hook_post_source='''
  let $NVIM_LISTEN_ADDRESS=v:servername
'''
を dein_lazy.toml に、
"scriptencoding utf-8
" vim:set ts=4 sts=2 sw=2 tw=0 fenc=utf-8:

" vimtexの設定
let g:vimtex_view_general_viewer = 'SumatraPDF'
let g:vimtex_compiler_latexmk = {
  \ 'background' : 0,
  \ 'build_dir' : '',
  \ 'continuous' : 0,
  \ 'callback' : 1,
  \ 'executable' : 'latexmk',
  \ 'options' : [
  \   '-verbose',
  \   '-file-line-error',
  \   '-synctex=1',
  \   '-interaction=nonstopmode',
  \ ],
  \}

if has('nvim')
  " if running on Neovim
  let g:vimtex_compiler_progname = 'nvr'
  let g:vimtex_view_general_options
 \ = '-reuse-instance'
 \ . ' -forward-search @tex @line @pdf'
 \ . ' -inverse-search "nvr --servername ' . v:servername
 \ . ' --remote-send \"\%lG\""'
 \ . ' -console'
  let s:sumatra_args='-reuse-instance -inverse-search "nvr --servername ' . v:servername
   \ . ' --remote-send \"\%lG\""'
else
  if has('win32')
 " if running on Vim
 let g:vimtex_compiler_progname = 'c:/Apps/vim80/gvim'
 let g:vimtex_view_general_options = '-reuse-instance -forward-search @tex @line @pdf -inverse-search "c:\Apps\vim80\gvim --remote-silent +\%l \%f " -console'
 let s:sumatra_args='-reuse-instance -inverse-search "gvim --servername ' . v:servername
   \ . ' --remote-send \"\%lG\""'
  endif
endif

function Kick_SumatraPDF()
  execute '!start SumatraPDF' s:sumatra_args expand("%:t:r").'.pdf'
endfunction

nnoremap  :call Kick_SumatraPDF()
~/.config/nvim/vimtex-local.vim に保存します。
これで F8 キーでビューワが開いて逆方向検索もできるようになりました。

ここでは、以前にちゃんとビューワが開けなかったために明示的に Kick_SumatraPDF() という関数を作ってそれを実行させていますが、本来は <localleader>lv (ただし localleader は "\")でビューワが開くマッピングになっています。

簡単にまとめると、
  • \ll : vimtex-compile(コンパイルの実行)
  • \lv : vimtex-view(PDFの表示)
  • \lk : vimtex-stop (コンパイルの中止。ただしWindowsでは効かない)
  • \le : vimtex-errors(quickfixウィンドウの表示)
  • \lg : vimtex-status(コンパイルの状態を表示)
  • \lc : vimtex-clean(中間ファイル類を削除)
  • \li : vimtex-info(vimtexの状態を表示)
などとなっています。

余談ですが、TeXLive 2019 は今月末にリリースのようですね。

Windowsでシンボリックリンクを試してみる。

きっかけは、1つのファイルを別の名前で起動したら違う動きになるようなスクリプトを書く、でした。  busybox なんかでは、同じ実行形式ファイルの名前を、lsにすればlsと同じ、cpとすればcpと同じ動作をするようにしてますが、Pythonスクリプトでそれと同じように argv...