shellspec README.md 日本語版

shellspecのREADME.mdの日本語版です。

github.com

英語と日本語両方メンテナンスするのが嫌なので、日本語版はなくてもいいかなーとも思っていたんですが、気の迷いで書いちゃいました。(でもリポジトリには入れない予定)

頑張って英語で書いて、それを自分で日本語化するとかいう、なんという無駄感

あ、 Table of Contents のリンクがおかしいけど面倒なので直さないっす。ページ内検索でもしてください。

shellspec

POSIX互換シェルスクリプト用のBDDベースのテスティングフレームワーク

シェルスクリプトをテストしましょう!

f:id:koichi_nakashima:20190311010858p:plain

Table of Contents

イントロダクション

スペックファイル

Describe 'sample' # Example group block
  Describe 'bc command'
    add() { echo "$1 + $2" | bc; }

    Example 'perform addition' # Example block
      When call add 2 3 # Evaluation
      The output should eq 5  # Expectation
    End
  End

  Describe 'implemented by shell function'
    . ./mylib.sh # add() function defined

    Example 'perform addition'
      When call add 2 3
      The output should eq 5
    End
  End
End

特徴

  • POSIX互換シェルに対応 (dash、bash、ksh、busybox等)
  • BDD スタイルのシンタックス
  • シェルスクリプト言語の構文と互換性のあるスペックファイル
  • 純粋なシェルスクリプト実装
  • 最小限の依存関係 (僅かなPOSIX互換コマンドのみ使用)
  • ネスト可能なグループとレキシカルスコープ風のスコープの提供
  • Before / After フック
  • Skip / Pending 機能
  • モックとスタブ (一時的な関数のオーバーライド)
  • 内存の簡易タスクランナー
  • モダンなレポート (カラー対応, エラー行番号表示)
  • 拡張可能なアーキテクチャ (カスタムマッチャー、カスタムフォーマッター等)
  • shellspec は shellspec 自身でテスト

サポートシェル

dash, bash, ksh, mksh, pdksh, zsh, posh, yash, busybox (ash)

動作確認プラットフォーム

  • Linux (ubuntu, debian, alpine)
  • Windows 10 (WSL, cygwin, Git Bash)
  • macOS Mojave
  • Solaris 11

確認済み旧バージョン(このバージョン以降で動作するでしょう)

  • ash 0.3.8 (debian 3.0)
  • dash 0.5.3 (debian 4.0)
  • busybox ash 1.1.3 (debian 4.0)
  • bash 2.03 (debian 2.2)
  • zsh 3.1.9 (debian 2.2)
  • pdksh 5.2.14 (debian 2.2)
  • mksh 28 (debian 4.0)
  • ksh93 93q (debian 3.1)
  • ksh88 0.5.11 (solaris 11)
  • posh 0.3.14 (debian 3.1)
  • yash 2.30 (debian 7)

依存関係

shellspec はシェルスクリプトによって実装されているので、そのため動作に 必要なものはシェルと僅かなPOSIX互換コマンドのみです。

現在使用している外部コマンド

date, mkdir, rm, mv (推奨: printf, ps, readlink, time)

チュートリアル

インストール

shellspec をダウンロードしてPATHにシンボリックリンクを作成するだけです

$ cd /SOME/WHERE/TO/INSTALL
$ wget https://github.com/ko1nksm/shellspec/archive/{VERSION}.tar.gz
$ tar xzvf shellspec-{VERSION}.tar.gz

$ ln -s /SOME/WHERE/TO/INSTALL/shellspec-{VERSION}/shellspec /EXECUTABLE/PATH/
# (例 /EXECUTABLE/PATH/ = /usr/local/bin/, $HOME/bin/)

またはシンボリックリンクを作成するために shellspec を作成します (もし readlink がない場合)

$ cat<<'HERE'>/EXECUTABLE/PATH/shellspec
#!/bin/sh
exec /SOME/WHERE/TO/INSTALL/shellspec-{VERSION}/shellspec "$@"
HERE
$ chmod +x /EXECUTABLE/PATH/shellspec

入門

プロジェクトディレクトリを作成して shellspec --init を実行します。

# プロジェクトディレクトリの作成
$ mkdir <your-project-directory>
$ cd <your-project-directory>

# 初期設定
$ shellspec --init
  create .shellspec
  create spec/spec_helper.sh

# スペックファイルを作成します (好みのテキストエディタを使用できます)
$ cat<<'HERE'>spec/hello_spec.sh
Describe 'hello.sh'
  . lib/hello.sh
  Example 'hello'
    When call hello shellspec
    The output should equal 'Hello shellspec!'
  End
End
HERE

# lib/hello.sh の作成
$ mkdir lib
$ touch lib/hello.sh

# 関数を実装していないため失敗します
$ shellspec

# hello 関数の作成 (好みのテキストエディタを使用できます)
$ cat<<'HERE'>lib/hello.sh
hello() {
  echo "Hello ${1}!"
}
HERE

# 成功します
$ shellspec

サンプル

sample directoryを参照、 shellspec ディレクトリで shellspec sample で実行できます。

基本構造

これらのDSLで構造化された Example を記述できます。

DSL 説明
Describe Example group ブロックを定義します。Example group はネスト可能です。
Context Describe の別名です。
Example Example ブロックを定義します。 この中にexampleを書きます。
Specify Example の別名です。
End Example group または Example ブロックの終了です。
Todo 空の example と同じですが、ブロックではありません。実装予定を示すワンライナー構文です。

ネスト可能なグループとスコープ

スペックファイルは正当なシェルスクリプトの構文ですが、スコープや行番号を実装するために変換処理を行っています。

それぞれの example group ブロック と example ブロックはサブシェルに変換されます。 そのためブロックの中で行われた変更はブロックの外に影響を与えません。

つまりローカル変数とローカル関数をスペックファイルで実現しています。 これは構造化されたスペックを記述するのにとても便利です。

もしどのような変換が行われるのか興味がある場合は、 --translate オプションを使用してください。

一時的なブロックのスキップ

Describe, Context, Example, Specify ブロックの頭に x をつけて xDescribe, xContext, xExample, xSpecify とすることで一時的にブロックの実行をスキップできます。

フック

example の前後に実行されるフックを定義できます。

DSL 説明
Before example 実行前に呼ばれるフックを定義します。
After example 実行後に呼ばれるフックを定義します。

モック と スタブ

現在、shellspec はモックやスタブのための特別な関数は提供していません。 しかしシェル関数を再定義することで既存のシェル関数や外部コマンドをオーバーライドできます。 これをモックやスタブとして代用することが出来ます。

Describe, Context, Example, Specify ブロックがサブシェルで実行されることを思い出してください。 ブロックを抜けた時、オーバーライドした関数は元に戻ります。

Example

example ブロックは、仕様を記述する場所です。 最大一つの Evaluation と 複数の Expectations から構成されます。

Evaluation

検証のためのアクションを定義します。それぞれの Example は 最大一つの Evaluation を記述できます。

When call             echo hello world
     <- evaluation type ->
DSL 説明
When evaluation を定義します。
evaluation type 説明
call シェル関数または外部コマンドを実行します。
invoke シェル関数または外部コマンドをサブシェルで実行します。
run 外部コマンドを実行します。

通常は call を使用することでしょう。 invokecall に似ていますが、サブシェルで実行します。 invokeevaluation のみで関数をオーバーライドしたい 時と exit をトラップしたい時に便利です。

Expectation

検証する内容を定義します。

DSL 説明
The The ステートメントを定義します。
It It ステートメントを定義します。

The ステートメント

これは一番基本的な Expectation です。検証対象(subject)が予想された値であるかを評価(Evaluate)します。

The output        should equal         4
    <- subject ->        <- matcher -> <- expected value ->

modifier は 評価前に subject を加工します。

The line 2  of     output        should equal 4
    <- modofier -> <- subject ->

modifier はつなげることが出来ます。

The word 1 of line 2  of    output        should equal 4
    <- multiple modifier -> <- subject ->

modifier の最初の引数が数値の場合は、代わりに序数を使用することも出来ます。

The second line of output        should equal 4
    <- modofier -> <- subject ->

It ステートメント

It ステートメントThe ステートメント のシンタックスシュガーです。長い主語を避けるために使用できます。

注意: rspecとは違い、ItExample の別名ではありません。

以下の2つの文章は同じ意味です。

The word 1 of line 2 of output should equal 4
It should equal 4 the word 1 of line 2 of output

ランゲージチェイン

shellspec は chai.js に似たランゲージチェインをサポートします。

ランゲージチェインは可読性を上げるためだけのものです。 Expectation の実行には影響を与えません。

  • a
  • an
  • as
  • the

以下の2つの文章は同じ意味です。

The first word of second line of output should valid number
The first word of the second line of output should valid as a number

Subject

検証を行う対象です。

Subject (検証対象) 説明
output
stdout
Evaluation の標準出力を subject として使用します。
error
stderr
Evaluation の標準エラー出力を subject として使用します。
status
exit status
Evaluation の終了ステータスを subject として使用します。
funciton <NAME> 関数実行の標準出力を subject として使用します。
path <PATH>
file <PATH>
dir <PATH>
(別名を解決した) パスを subject として使用します。
value <VALUE>
string <VALUE>
指定した値を subject として使用します。
variable <NAME> 指定した変数の値を subject として使用します。

Modifier

検証を行う対象を加工します。

Modifier 説明
line <NUMBER> subject の指定された行を subject として使用します。
lines subject の行番号を subject として使用します。
word <NUMBER> subject の指定された単語を subject として使用します。
contents ファイルの中身を subject として使用します。 (現在の subject はファイルパスであること)
length subject の長さを subject として使用します。

Matcher

検証を行う処理の内容です。

exit status (subjectは終了ステータスであることを想定)

Matcher 説明
be success 終了ステータスは成功であること
be failure 終了ステータスは失敗であること

stat (subjectはファイルパスであることを想定)

Matcher 説明
be exist ファイルは存在していること
be file ファイルはファイルであること
be directory ファイルはディレクトリであること
be empty ファイルは空であること
be symlink ファイルはシンボリックリンクであること
be pipe ファイルはパイプであること
be socket ファイルはソケットであること
be readable ファイルは読み取り可能であること
be writable ファイルは書込み可能であること
be executable ファイルは実行可能であること
be block_device ファイルはブロックデバイスであること
be charactor_device ファイルはキャラクターデバイスであること
has setgid ファイルは setgid フラグを持っていること
has setuid ファイルは setuid フラグを持っていること

valid

Matcher 説明
be valid number subject は数字として正しいこと
be valid funcname subject は関数名として正しいこと

variable (subject は変数名であることを想定)

Matcher 説明
be defined 変数は定義されていること (set)
be undefined 変数は未定義であること (unset)
be blank 変数は空であること (unset または 空文字)
be present 変数は存在すること (空文字でない文字列)

string

Matcher 説明
start with <STRING> subject は <STRING> で始まっていること
end with <STRING> subject は <STRING> で終わっていること
equal <STRING> subject は <STRING> と一致していること
include <STRING> subject は <STRING> を含んでいること
match <PATTERN> subject は <PATTERN> とマッチすること

other

Matcher 説明
satisfy <FUNCTION> [ARGUMENTS...] subject <FUNCTION> を満たすこと

Helper

DSL 説明
Set 変数に値を代入します。
Unset 変数を未定義にします。
Path
File
Dir
パスの別名を定義します。
Debug デバッグメッセージを出力します

Path alias

読みやすさのために長いパスに短い名前を定義することが出来ます。

Example 'not use path alias'
  The file "/etc/hosts" should be exist
End

Example 'use path alias'
  File hosts="/etc/hosts"
  The file hosts should be exist
End

Skip と Pending

現在実行しているブロックを Skip または Pending します。

DSL 説明
Skip <REASON> 現在のブロックを Skip します。
Skip if <REASON> <FUNCTION> [ARGUMENTS...] 現在のブロックを条件付きで Skip します。
Pending <REASON> 現在のブロックを Pending します。

shellspec コマンド

デフォルトオプションの設定

shellspec コマンドのデフォルトオプションを変更する場合は、オプションファイルを作成します。 以下の順番で読み込みを行い、オプションを上書きます。

  1. $XDG_CONFIG_HOME/shellspec/options
  2. $HOME/.shellspec
  3. ./.shellspec
  4. ./.shellspec-local (VCSで管理しないでください)

タスクランナー

--task オプションでタスクの実行を行います。

環境変数

Name 説明
SHELLSPEC_ROOT shellspec ルートディレクトリ 指定されていない場合は自動的判定します。(もし readlink がない場合は失敗するでしょう)
SHELLSPEC_LIB shellspec lib ディレクトリ 指定されていない場合は $SHELLSPEC_ROOT/lib
SHELLSPEC_LIBEXEC shellspec libexec ディレクトリ 指定されていない場合は $SHELLSPEC_ROOT/libexec
SHELLSPEC_TMPDIR shellspec が使用する一時ディレクトリ 指定されていない場合は $TMPDIR or /tmp
SHELLSPEC_SPECDIR スペックファイルのディレクトリ 現在のディレクトリ下の spec ディレクトリです
SHELLSPEC_LOAD_PATH ライブラリのロードパス $SHELLSPEC_SPECDIR:$SHELLSPEC_LIB:$SHELLSPEC_LIB/formatters

スペックディレクトリ以下の特殊ファイルとディレクトリ

spec/spec_helper.sh

spec_helper.sh--require spec_helper オプションでロードされます。

このファイルは example の実行のための準備を行います。(カスタムマッチャーの定義等)

spec/support/

このディレクトリはカスタムマッチャーやタスクファイルを作成に利用されます。

spec/banner

もし spec/banner ファイルがある場合、shellspec コマンド実行時にバナーを表示します。 バナー表示を無効にする場合は --no-banner オプションを使用します。

qiitaにシェルスクリプトのecho関連の記事を2本投稿しました

qiita.com

qiita.com

こういう記事はqiitaに書くかブログに書くか迷いますね。

とりあえず技術的な話はqiitaに書いたとして、ここには雑談的なことを書くことにしましょう。

echoに関するのこの問題は、shellspec の開発中に問題になりました。

shellspecはPOSIX互換のシェルで動く方針であるため、各シェルの互換性問題を解決しなければなりませんでした。一番基本であるechoに互換性がなかったのは辛かったですね。

shellspecはユーザーが書いた文字列をエラーメッセージとして(しかも色付きで)表示することがあるため、文字列にエスケープシーケンスが入る可能性を否定できません。引数の文字列をそのまま出力する必要があります。文字列をそのまま出力するには printf '%s\n' を使えば良いのですが、そうすると一部のシェルで極端に遅くなってしまいました。ビルトインではなく外部コマンドのprintfを呼び出しているからです。WSL上だとさらに遅くなってしまいました。

printfがなくともZSHやKSHでは似たような事ができるprintが使えるので問題ないのですがposhが大変でした。(使ってる人は殆ど居ないと思うんですが)

poshはprintfはビルトインではない。printはない。どうしたもんかと。仕方がないのでエスケープ文字の\\\に変換するようロジックで頑張ることになりました。まあ大したコードじゃないですけどね。

もちろんそのテストはshellspec自身で行っています。

ターミナル操作のデモ動画作成用のツール (ghostplay) を作った

こういうのをやりたかったんですよ。

これは https://shellspec.info に載せているデモ動画です。何も知らない初見さんに対して、実際に使ってもらうことなくどういう事ができるというのをぱっと見せることが出来ます。

この動画は、動画の右下にも書いてあるように asciinema - Record and share your terminal sessions, the right way というサービスを利用しています。 shellspec が大きく影響を受けている rspec で使っているのを見て知りました。実はこれ画像ではなくテキストなのでコピペできるんですよ。

asciinema はターミナル操作を録画して、それをシェアするためのツールです。

ただですね? ターミナルを操作するのは人間なんですよ。

ライブコーディングとか一発勝負、ミスも含めて全部録画。みたいなのであればそれでも良いのですが、プログラム紹介のデモ動画にそこまでの緊張感やライブ感はいりません。また将来修正が入るかもしれませんし、そのたびに長い文章を何度も入力するなんで面倒な作業ですよね?

ということで作ったのが、スクリプトの自動入力ツール ghostplay です。

github.com

使い方は簡単で、

1. 適当なシェルスクリプトを書きます。

[example/script.sh]

#!/bin/sh
echo This is your script.
echo ghostplay types your script and execute.

2. ghostplayを使用して実行します。

ghostplay example/script.sh

するとこのようにスクリプトを1文字1文字入力して実行します。(まるで幽霊が演奏するかのように)

f:id:koichi_nakashima:20190304181428g:plain

↑これは asciinema ではなく ttyrec で録画したものを seq2gif でアニメーションGIFに変換しています。GitHubのREADME.md に乗せる場合に便利です。

ghostplay 自体はスクリプトの自動入力ツールなので、ターミナル操作の録画を行う時は asciinema や ttyrec と組み合わせて使います。 asciinema と ttyrec の両方に録画開始と同時にコマンド実行するオプションがあるので以下のように簡単に連携させることが出来ます。

asciinema

# Record terminal
asciinema rec -c "ghostplay example/script.sh"

ttyrec & seq2gif

# Record terminal to a file "ttyrecord'
ttyrec -e "ghostplay example/script.sh"

# Convert to animated gif
seq2gif -i ttyrecord -o demo.gif

類似ソフト

spielbash

似たようなソフトに spielbash というのを見つけました。リポジトリが複数あって分かりづらいのですが以下のような関係みたいです。

  1. https://github.com/redhat-cip/spielbash オリジナル? 2016年頃に開発。Python製
  2. https://github.com/justinazoff/spielbash 1.をフォークして2017年頃に修正を加えたもの
  3. https://github.com/Malinskiy/spielbash 1.をRubyで書き直したもの。2018年頃に開発。多分一番高機能。

おそらく機能的には spielbash の方が上です。ghostplay ではシェルスクリプトで自動実行できるものを対象としているため vim や irb 等の対話型ツールを自動操作できませんが spielbash (3.のやつ) では scenario_1.yaml を見る限り、それができるようです。

それに対する ghostplay の優位性はスクリプトファイルの記述が簡単であるという点です。ghostplay のスクリプトファイルはシェルスクリプトそのものです。(実際にシェルスクリプトとしてシェル上で実行しています。)操作内容を書いたシェルスクリプトを作成すれば、それがそのまま(もしくはわずかな修正で) ghostplay のスクリプトファイルとして使用できます。

GitHub Pages + 独自ドメイン + HTTPS (SSL) でサイトを公開した

何番煎じかわからないネタですが、自分の備忘録としてGitHub Pages + 独自ドメイン + HTTPS (SSL) でサイトを公開したときの方法を書きます。

作成したサイトは 、この間作成したシェルスクリプト用のテスティングフレームワーク shellspec の公式サイトです。必要ないかなーとも思っていたのですが、もう少し検索に引っかかって欲しくなったので。ドメインもとっちゃったし。

shellspec.info

やること

  • GitHub Pagesでウェブサイト作成
  • 独自ドメインのためのDNS設定
  • 独自ドメイン + HTTPS (SSL) 有効化
  • その他

GitHub Pages でウェブサイト作成

まずは独自ドメインのことは一旦忘れて、GitHub Pages でウェブサイトを作成します。サイトの目的は github のプロジェクトページへの流入を増やすためで詳細な説明などをする予定はありません。トップページ1枚程度で shellspec がどんなものかをざっくり見せるだけのものとします。

GitHub Pages でウェブサイトを作成するにリポジトリにサイトのソースコードを入れて設定するだけですが、以下のいずれかから選ぶ必要があります。

  1. master ブランチ
  2. master ブランチの docs フォルダ
  3. gh-pages ブランチ

今回は、shellspec リポジトリとは別管理にしたかったので、shellspec.info 専用のリポジトリ shellspec-website を作成し 、1. の master ブランチからウェブサイトを作成することにしました。

まずはプロジェクトの Settings から GitHub Pages の設定に移動します。

f:id:koichi_nakashima:20190304131016p:plain

Source の項目に「gh-pages branch]「master branch」「master branch /docs folder」「None」とあるので 「master branch」を選びます。(「gh-pages branch」はGitHubにgh-pagesブランチがなければ表示されません)

余談ですが、gh-pages ブランチを使用した場合の例をぐぐってみると、master ブランチから gh-pages ブランチを作成しているのをよく見かけたのですが、通常 master ブランチは伸びていくものなので、そこから gh-pages ブランチを枝分かれさせるのは気持ち悪い気がします。gh-pages ブランチを使用してプロジェクトと GitHub Pages を同じリポジトリに作成する場合は、master ブランチと切り離して gh-pages ブランチを作成したほうが良いと思います。(つまり git checkout --orphan gh-pages を使用して gh-pages ブランチを作成するということです。)

設定を終えると次のような画面になり、ウェブサイトのURL (https://ko1nksm.github.io/shellspec-website/) が表示されます。

f:id:koichi_nakashima:20190304161252p:plain

設定は終わりましたが、ウェブサイトが更新されるタイミングはリポジトリにpushしたタイミングみたいなので、リポジトリの README.md (もしくは index.md)に適当な内容を書いて github に pushします。(更新まで少し数十秒程度時間がかかることがあるようです。)

トップページは index.md があれば index.md、なければ README.md が使用されるようです。markdownを使いたくない場合は、拡張子をhtmlにしてHTMLを書くことも出来ます。markdownで書いた場合、対応するHTMLが自動的に作成されます。(例えば index.md であれば、index.html が作成されます。ただし README.md からも index.html が作成されます。)

さて、これでGitHub Pagesでサイト作成ができたわけですが、少しさみしいのでデザインを調整してみます。GitHub Pages の設定の Theme Chooser からテーマを選ぶとテーマが反映されます。この時リポジトリに _config.yml が追加・更新されるので注意してください。

独自ドメインのためのDNS設定

次にGitHub Pagesでカスタムドメインの設定を行う前に、DNS設定を行います。DNS設定のやり方は使用しているDNSサービスによって違います。

まず方針として最終的に https://shellspec.info でウェブサイトを公開するわけですが、これは www などのサブドメインのない apex domain です。この場合の DNS 設定方法には「ALIASレコードを使用する」「ANAMEレコードを使用する」「Aレコードを使用する」の3通りあります。

help.github.com

ALIASレコード または ANAMEレコード であれば、IPアドレスを書かずに簡単にかけるのですが、shellspec.info で使用している namecheap ではサポートされていません。なのでAレコードを使用して設定しました。(IPアドレスは変更になることがあるかもしれないので 最新の github のドキュメントを参照してください)

f:id:koichi_nakashima:20190304170307p:plain

しばらく待って、shellspec.info でgithubのIPアドレスが引けるようになれば完了です。

独自ドメイン + HTTPS (SSL) 有効化

GitHub Pagesの設定に戻ります。独自ドメインに切り替えるには、custom domain の設定に使用するドメインを設定するだけです。 custom domain の設定を有効にするとリポジトリに独自ドメイン名が書かれた CNAME ファイルが追加されます。

f:id:koichi_nakashima:20190304171028p:plain

設定を行うと、https://ko1nksm.github.io/shellspec-website/http://shellspec.info に変わり、旧URLにアクセスすると独自ドメインのURLにリダイレクトするようになります。

独自ドメインの設定が終わってもHTTPSが有効にならない場合があります。(Enforce HTTPS が押せない。)これはDNSの設定が正しく設定されてないか、GitHubがまだIPアドレスを引けないからです。(DNSの設定に問題がなければ)しばらく待てば有効にできるようになると思います。

Enforce HTTPS を有効にすれば、HTTPS対応も完了です。証明書は Let's Encrypt のものが使用されていました。はてなブログもそうですが、Let's Encrypt ができてから独自ドメインでも自分で証明書を取ることなく簡単にHTTPS対応ができるようになったので便利ですね。

  • その他

公開した後は、プロジェクトURLの設定だとか、サイトマップの生成だとか、Googleアナリティクスの設定だとか、サイトの内容を書くとかするわけですが、GitHub PagesではJekyllが使用されているので、あとは Using Jekyll as a static site generator with GitHub Pages - GitHub Help とか Jekyll • Simple, blog-aware, static sites | Transform your plain text into static websites and blogs を参照しつつ作業します。

今はテーマ (jekyll-theme-slate) のCSSを少し調整して、_config.yml を書き換えた程度です。

サブドメインなし→ありへのリダイレクトに namecheap の URL Redirect Record が便利だった

このブログは、はてなブログを使用しているのですが、独自ドメインで運用する時はサブドメインを設定する必要があるようです。

help.hatenablog.com

サブドメインでブログを運用すること自体は別に問題ないんですが、サブドメインなしの http://nksm.name にリンクしている所があったので、サブドメインなしでアクセスしたら、https://blog.nksm.name にリダイレクトさせようと思いました。

リダイレクトさせるには例えば .htaccess にリダイレクト設定を記述すれば良いのですが、その .htaccess を配置するサーバーが必要になってきます。一応VPSサーバーをレンタルしているので配置するサーバーはあるのですが、現在はプライベートリポジトリ用のgitlabにしか使用しておらず、GitHubのプライベートリポジトリが無料になったのでVSPサーバーを解約しようと思っています。もしサーバー立てたくなったらその時はクラウドでも使えばいいですし。

なので、どこか無料で.htaccessが使えるサーバー無いかなと探していたのですが、現在使用しているレジストラの namecheap にそういう機能があったのを思い出しました。(今まで気にしたことがなかったのですが、URL転送などの名称で提供してる所がいくつか見つかりますね)

www.namecheap.com

設定方法は、Domain List から対象のドメインの [MANEGE] をクリックして、Advanced DNS から TypeURL Redirect Record のレコードを追加するだけです。

f:id:koichi_nakashima:20190224213029p:plain

赤枠の一行上の、CNAME Record の行が、はてなブログを独自ドメインで運用するための CNAME の設定で、赤枠の行でサブドメインなし(@)でアクセスされたら、https://blog.nksm.name にリダイレクトするという設定を行っています。Value の値にはリダイレクトのタイプを指定することができ、 Permanent (301)(301リダイレクト)、Unmasked (302リダイレクト)、Masked(URL frame)が選べるようです。

設定後 nksm.name のIPアドレスを調べてみた所、namecheap 管理だと思われる IPアドレスが返ってきたので、http://nksm.name にアクセスしたら一旦 namecheap のウェブサーバーが受け取り、 https://blog.nksm.name にリダイレクトさせるという仕組みのようです。

ということで、namecheap の URL Redirect Record の機能のおかげで、追加でサーバーをレンタルすることなく実現することが出来ました。