panda's tech note

Windows Subsystem for Linux (WSL)

(2018年3月1日更新)

Windows 10 Fall Creators UpdateからWindows上でLinuxプロセスを動かすシステムである,Windows Subsystem for Linux (WSL)が正式版として提供されています。Windows上でUbuntuを動かし,bashなどのシェルを使うことができます。

Ubuntu on WSL

Ubuntuの配布元であるCanonicalがWSL対応のUbuntuをMicrosoft Storeで配布していますので,こちらから簡単にインストールできます。

SSH Agent

まず,SSHの秘密鍵・公開鍵のペアを作っていなければ作ります。これは初回のみ行えばよいです。以下の例では4096ビットのRSA鍵ペアを作成します。

$ ssh-keygen -b 4096 -t rsa

次にSSH Agentを起動します。SSHクライアントは環境変数SSH_AUTH_SOCKに設定されいているソケットファイルを通じてSSH Agentにアクセスしますので,SSH Agentを起動後,環境変数を設定する必要があります。以下のコマンドではssh-agent -sで標準出力に出力される環境変数設定コマンド(bash形式)をevalで評価することでSSH_AUTH_SOCKSSH_AGENT_PID(プロセスID)の環境変数を設定しています。

$ eval `ssh-agent -s`
Agent pid 1100

これでSSH Agentの設定が終わりました。

次にSSH Agentに鍵を登録します。ssh-keygenで作成した鍵(秘密鍵)は~/.ssh/id_rsaに保存されていますので,そのパスを指定します。秘密鍵のパスフレーズを求められるので入力すればOKです。

$ ssh-add -k ~/.ssh/id_rsa
Enter passphrase for /home/user/.ssh/id_rsa:

これで,SSH Agentの設定と鍵の設定は完了です。SSHのたびに鍵のパスフレーズを求められることがなくなります。

SSH Agentの自動起動

WSLだとサービスの自動起動を書くことが想定されていないようで,(2018年3月1日に調べた限りでは)startup scriptを書くことができません。SSH Agentを毎回手動で起動するのは大変ですし,screenなどで複数のシェルで環境変数を設定するのも大変なので,以下のように.bashrcにSSH Agentの自動起動コマンドを書きました。二重起動やsudoしたときにユーザを区別できるような工夫が入っています。

uid=$(id --user)
if [ -z "$(pgrep ssh-agent -U ${uid})" ]; then
  for f in `find /tmp -name "ssh-*" -uid ${uid} 2> /dev/null`; do
    rm -rf $f
  done
  eval $(ssh-agent -s) > /dev/null
else
  export SSH_AGENT_PID=$(pgrep ssh-agent -U ${uid})
  export SSH_AUTH_SOCK=$(find /tmp/ssh-* -name agent.* -uid ${uid} 2> /dev/null)
fi

Screen

Ubuntu on WSLでscreenを起動すると以下のようにPermission deniedエラーになります。

$ screen
Cannot make directory '/var/run/screen': Permission denied

/var/run/screenがないことが原因なので

$ sudo mkdir /var/run/screen && sudo chmod 0777 /var/run/screen

を実行するか,

$ sudo /etc/init.d/screen-cleanup start

screenの初期化をすると/var/run/screenが作成され,screenを使えるようになります。ただ,/var/run/screenはUbuntu on WSLのシェルウィンドウを閉じると削除されてしまうようです。これを回避するためには,以下のように削除されないパスにscreenを作成し,$SCREENDIR環境変数にそのパスをセットします。

$ mkdir ~/.screen && chmod 0700 ~/.screen
$ export SCREENDIR=$HOME/.screen

私は

export SCREENDIR=$HOME/.screen

.bashrcに書いています。