TORIPIYO DIARY

recent events, IoT, programming, security topics

Restart nodejs application on file change or error output in "heroku local" command

This article is English translation of http://toripiyo.hatenablog.com/entry/2018/03/11/185532 Japanese article.

I am deploying nodejs application on heroku platform as production. In local environment I use "heroku local" command to run application on local machine.
I googled to find a way to make nodejs application automatically restart on file change or error message output by "heroku local" command.
However I couldn't find a proper article to explain it. So I would like to summarize it as note to myself.

By following below steps, the application can automatically restart on file change or stop by error message output.

0. install forever

npm install forever -g

1. insert below line on Procfile which located on application's root directory

development: forever -w -m 500 -c "node --inspect=5858" app.js
  • -w option is used to restart application on file change
  • -m option is used to specify how many times restart application (in this example the application can be restarted 500 times if error output stops the application)
  • -c option is used to specify the command which executed when "heroku local development" command is run. --inspect option is used to open 5858 port for debug purpose.

2. put .foreverignore file on application root directory

(.foreverignore)
=====================================
**/.idea/**
**/.git/**

**/.tmp/**
**/views/**
**/assets/**

# Restart only when js files are changed.
!*.js
=====================================
  • notice: .foreverignore writing style is different from .gitignore style. the application can decide to restart by referring to .foreverignore contents.

foreverignore syntax/documentation · Issue #417 · foreverjs/forever · GitHub


3. run application with "heroku local" command

heroku local development

By following above steps, the application which managed by "heroku local" command can automatically restart even on file change or stop by error message output.

Dockerを利用してローカル環境のmongoDBをhomebrewの3.2からdockerコンテナの3.6に移行させる

現在開発中のアプリケーションで利用しているmongooseをバージョンアップさせたら正しくアプリケーションが動作しなくなり、直すには、mongoDBのバージョンを3.6に上げることが必要なことがわかりました。
ローカル環境のmongoDBは、brew install mongoでインストールしたmongoDB 3.2系を利用していたので、brew upgrade mongodbを実行して3.6系にバージョンを変更。
これで、問題なく動くようになると思ったら、、、

mongod --config /usr/local/etc/mongod.conf

を実行すると以下のメッセージが表示されてmongoDBを起動出来ません。

2018-03-12T00:01:13.020+0900 F CONTROL  [initandlisten] ** IMPORTANT: UPGRADE PROBLEM: The data files need to be fully upgraded to version 3.4 before attempting an upgrade to 3.6; see http://dochub.mongodb.org/core/3.6-upgrade-fcv for more details.
2018-03-12T00:01:13.020+0900 I NETWORK  [initandlisten] shutdown: going to close listening sockets...

エラーメッセージを見た限りでは、/usr/local/var/mongodbに置いてあるデータは、異なるバージョン間では互換性が無いようでうまく読み込みが出来ない様子。そこで、mongoDB3.2からデータをダンプして、mongoDB3.6にダンプしたデータを読み込ませることにしました。

brew switch mongodb 3.2.1 

でバージョンを3.6から3.2に戻して、

mongodump -v --out data-`date +"%m-%d-%y"` 

を実行すると、なぜかコマンドから応答が帰ってこなくてdumpファイルを取得できない。もしかしたら、正しい場所に繋ぎに行こうと出来ていないのかもしれませんが、原因わからず。ここまで来て、dockerを使ってデータのダンプとリストアを実行することにしました。

mongoDB 3.2からdumpファイルの取得

まず、mongoDB3.2のコンテナを動かします。この時、ローカル環境のmongoDBデータを読み込ませられるように、-vオプションでローカルの/usr/local/var/mongodbを、コンテナの/data/dbパス上にマウントさせます。

docker run --name mongo-3.2 -v /usr/local/var/mongodb:/data/db -d mongo:3.2

稼働しているmongo-3.2コンテナに対して、mongodumpコマンドを実行してdumpファイルをmongo-3.2コンテナ上の/tmpディレクトリ配下に作成します。

docker exec mongo-3.2 mongodump -v --out /tmp/data-`date +"%m-%d-%y"`

コンテナ上のdumpファイルをローカル上にコピーします。

docker cp mongo-3.2:/tmp/data-`date +"%m-%d-%y"` .

これで、dockerを利用してmongoDBのdumpファイルを取得できました。

mongoDB 3.6でdumpファイルの読み込み

mongoDB3.6のコンテナを稼働させて、mongoDB 3.2から取得したdumpファイルを読み込ませるようにします。3.6ではdockerボリューム上にデータを置きたいので、まず、mongoDB用のdockerボリュームを作成します。

docker volume create db

mongoDB 3.6を稼働させます。-vオプションで、dbボリュームをコンテナの/data/dbパスにマウント。-pオプションで、ローカルマシンの27017ポートに繋ぐとコンテナの27017ポートに転送されるように設定します。

docker run --name mongo-3.6 -v db:/data/db -p 27017:27017 -d mongo:3.6

ローカル上のdumpファイルをmongoDB 3.6のコンテナ上にコピーします。

docker cp data-`date +"%m-%d-%y"` mongo-3.6:/tmp

稼働しているmongoDB 3.6のコンテナに対して、mongorestoreコマンドを実行させてdumpデータを読み込ませます。

docker exec mongo-3.6 mongorestore /tmp/data-`date +"%m-%d-%y"`


===========================================

これで、homebrewでインストールしたmongoDB 3.2を、dockerコンテナのmongoDB 3.6コンテナに切り替えることができるようになりました。これからは、ローカル環境のmongoDBはdockerで管理したいと思います。

heroku localでnodejsアプリを起動した時にファイルの変更やエラーによる停止を検知して再起動するように設定

開発しているnodejsアプリケーションの本番環境はherokuにデプロイしているのですが、ローカル環境ではheroku localコマンドを利用してローカルマシンにアプリケーションを立ち上げています。
heroku localによるアプリケーションの立ち上げ時に、ファイルの変更やエラーによるアプリケーション停止を検知して、アプリケーションが自動で再起動されるようにする方法を調べたのですが、まとまったページがなかったのでメモもかねて記載しておこうと思います。

以下のように設定すれば、heroku localによる起動でも、ファイルの変更やアプリケーションエラーによる停止時にアプリケーションは再起動されるようになります。

0. foreverをインストール

npm install forever -g

1. アプリケーションのルートディレクトリにあるProcfileに以下の行を追加

development: forever -w -m 500 -c "node --inspect=5858" app.js
  • -wオプションは、ファイルの変更を検知して再起動がかかるようにするために必要
  • -mオプションは、何度再起動をかけるようにするか設定(ここではとりあえずエラーによって停止しても500回は再起動されるようにしている)
  • -cオプリョンは、heroku local developmentコマンドの実行時に、内部で実行するコマンドを指定。アプリケーションのデバッグ用に5858ポートを立ち上げるように--inspectオプションを指定している

2. .foreverignoreファイルをアプリケーションのルートディレクトリに配置

(.foreverignore)
=====================================
**/.idea/**
**/.git/**

**/.tmp/**
**/views/**
**/assets/**

# Restart only when js files are changed.
!*.js
=====================================
  • .foreverignoreは、gitignoreの書式とは異なる書き方をするので注意。.foreverignoreによって、どのファイルの変更時にはアプリケーションの再起動が必要なのか設定することができます。

foreverignore syntax/documentation · Issue #417 · foreverjs/forever · GitHub


3. アプリケーションを起動

heroku local development

以上の手順を踏めば、heroku localによる起動でも、ファイルの変更やエラーによるアプリケーション停止時にnodejsのアプリケーションは再起動されるようになります。

英語の文章を読む必要性

直接技術の話ではないですが、昨日、javascriptでcall関数とはどういう関数なのか調べました。まず、googleで、"javascript callとは"で検索をかけます。そうすると、いくつかのcallに関する説明のページが出てきます。ただ、自分のjavascriptに関する理解が足りないのかいまいちよくわかりません。調べだしてから1時間ぐらいが経過しました。いくつか記事を読んだ後でもまだはっきりと理解している自信が持てません。。

そこで、"javascript call"で検索してみました。MDNとW3Schoolsのページがトップに表示されます。

developer.mozilla.org

JavaScript Function call()


両方とも英語ですが、この2個の記事はcall関数の説明についてより洗練されて、簡潔に記述されていました。日本語の方がいい記事が見つかる時もよくあるのですが、今回は、始めから英語の記事含めて調べていれば時間を短縮することが出来ました。
日本語だけでも、もっといろんなページをあたれば理解できるのかもしれませんが、英語がちょっと読めれば圧倒的に早く正確に理解できることがよくあります。
さんざん言われていることですが、エンジニアとして効率的に技術を身に付けたいのであれば、英語は必須ですね。

dockerでrailsとpostgresqlのアプリ開発環境をローカルマシンに構築

railsアプリをローカルマシンで開発する環境をdockerで構築します。基本的に、Quickstart: Compose and Rails | Docker Documentationの内容を元にしています。

docker for macをインストール

dockerを利用するためには、もちろんdockerが必要なので、docker for macをインストールします。
Install Docker for Mac | Docker Documentation
他のサイトにもたくさん解説があると思うので、具体的なインストール方法をここでは省略します。インストールが完了して、docker for macが動いているとMacの右上のステータスバーにdockerのアイコンが表示されます。
https://docs.docker.com/docker-for-mac/images/whale-in-menu-bar.png

ちなみに、docker for macは、virtualboxlinuxマシン上にdockerエンジンを起動して動かしていると思っていたのですが、virtualboxではなくてHyperKitというテクノロジーを使っているそうです。virtualboxを利用するのは、docker toolboxということでした。
Docker for Mac vs. Docker Toolbox | Docker Documentation

railsアプリケーション用のイメージとコンテナの作成

アプリケーションで利用するrailsコンテナのイメージを、rubyのイメージから作成します。まず適当に、アプリケーションを入れるディレクトリを作成します。(sample-appとか適当な名前でいい。)ディレクトリ内にDockerfileという名前のファイルを作成します。

Dockerfile

FROM ruby:2.4.3
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

上記のファイルでは、以下を指定しています。

  • ruby2.4.3 のイメージを元に新しいイメージを作成
  • RUN apt-get ~~~ でrailsアプリケーションの実行に必要なパッケージをインストール
  • /myappディレクトリを作成して、/myapp配下で作業を行う
  • /appディレクトリ配下にGemfileとGemfile.lockを置いて必要なgemパッケージをインストール
  • gemパッケージのインストール後にアプリケーションのソースコード一式を/myapp配下に配置

次に、同じディレクトリ内に、GemfileとGemfile.lockを作成します。

Gemfile

source 'https://rubygems.org'
gem 'rails', '5.0.0.1'

Gemfile.lock

(空ファイル)

最後に、docker-compose.ymlファイルを同じディレクトリに作成します。

docker-compose.yml

version: '3'
services:
  db:
    image: postgres
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

docker-compose.ymlファイルでは、以下を指定しています。

dbコンテナ

  • postgresのイメージからdbコンテナを作成

webコンテナ

  • Dockerfileの情報を元にwebコンテナを作成
  • コンテナを立ち上げると"bundle exec rails s -p 3000 -b '0.0.0.0'"をデフォルトで実行するように設定
  • ローカルマシン上のソースコードをコンテナの/app配下で共有できるようにマウント
  • ローカルマシンの3000ポートに繋げると、コンテナ側の3000に接続されるように設定
  • webコンテナはdbコンテナが必要なので、dbコンテナが先に起動するように指定


必要なファイルを作成したら以下のコマンドをディレクトリ内で実行します。

docker-compose run web rails new . --force --database=postgresql

上記コマンドは、docker-compose.ymlの情報をもとに、webとdbコンテナが作成され、webコンテナに"rails new . --force --database=postgresql"のコマンドを実行させています。(--forceオプションで既にあるファイルを強制的に上書き、--databaseでデータベースにpostgresqlの利用を指定。)
これで、railsアプリケーションのテンプレートがディレクトリ内に作成されるので、テンプレート内のファイルを修正して効率的に開発作業を進めることが出来ます。

webコンテナ用イメージの再ビルド

"rails new . --force --database=postgresql"の実行後、Gemfile, Gemfile.lockの内容が書き換えられるので、ファイル内容の変更が反映されたwebコンテナのイメージを作成するために、以下コマンドを実行してイメージを再度ビルドさせます。

docker-compose build

これで、webコンテナのイメージにはGemfile, Gemfile.lockファイルの更新が反映されたものになり、イメージ内ではGemfileに記述されたgemパッケージのリストがインストールされた状態になります。
開発を進めてgemを追加した場合は、その度にイメージの再ビルドが必要となります。

データベースの接続設定

ここまでの設定では、webコンテナからdbコンテナのデータベースに繋ぐ設定がまだありません。アプリケーションのルートディレクトリ以下にあるconfig/database.ymlにあるファイルを修正してデータベースに接続できるようにします。webコンテナからは、dbというホスト名でIPを取得出来るようになっているので、host:にはdbを指定しています。

database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test

これで、データベースの接続設定は完了です。必要な設定は終わったので、webとdbコンテナを起動させます。

docker-compose up -d

を実行すると(-dオプションでバックグラウンドでの起動を指定)、webとdbコンテナが起動されます。ブラウザで http://localhost:3000 に繋ぐと下記のようなWelcomeメッセージが表示されるはずです。
f:id:ha107chan:20180206224804p:plain

dbコンテナのpostgresqlにデータベースを作成するには、下記を実行すればdatabase.ymlの設定に基づいてdbコンテナにデータベースが作成されます。

docker-compose run web rake db:create

コンテナの停止

docker-compose stop

コンテナの削除
(データベースのデータもvolumeに保存していない場合は消えるので注意)

docker-compose down

です。


======================================================

以上で、ローカル環境でdockerを使ったrailsアプリ開発の基盤が出来ました。これで、ローカルマシン上でソースコードを書いていけば、webコンテナにアクセスして動作を確認しながら開発を進めていくことができます。データベースのデータを永続化出来るようにvolumeに保存するとか、設定ファイルを修正したら自動でrailsを再起動させるとか、慣れてきたら自分の設定を調べながら追加していくといいと思います。

perlのワンライナーで文字列を置換する(初心者向け)

たまに、趣味や仕事でperlワンライナーで文字列置換をするのですが、そのたびに置換方法を忘れているので、ワンライナーで文字列を置換する時に知っておきたいことをまとめました。

目次

perlワンライナーで置換表現のサンプル

サーバの管理でよく遭遇する例です。

1. /etc/passwdの設定ファイルを修正する
/etc/passwdのバックアップファイル(ファイル名の末尾に.backupの文字列を付与)を作成して、ユーザのデフォルトshellをbashからzshに変更する

perl -pi.backup -e 's;/bin/bash;/bin/zsh;g' /etc/passwd

diff -U0 /etc/passwd.backup /etc/passwd
@@ -1 +1 @@
-root:x:0:0:root:/root:/bin/bash
+root:x:0:0:root:/root:/bin/zsh


2. apacheの設定ファイルを修正する
apacheの設定ファイルで、バックアップファイル(ファイル名の末尾に日付を付与)を作成して、MinSpareThreadsを75から125に変更する。
(^\s*MinSpareThreads\s+)の箇所は、(行の先頭からの空白文字列)MinSpareThreads(空白文字列)の文字列と一致して、一致した箇所が${1}に挿入されています。

perl -pi.$(date +%Y%m%d) -e 's;(^\s*MinSpareThreads\s+)\d+;${1}125;g' httpd-mpm.conf

diff -U0 httpd-mpm.conf.20180131 httpd-mpm.conf
@@ -46 +46 @@
-    MinSpareThreads         75
+    MinSpareThreads         125
@@ -63 +63 @@
-    MinSpareThreads         75
+    MinSpareThreads         125
@@ -83 +83 @@
-    MinSpareThreads         25
+    MinSpareThreads         125
@@ -97 +97 @@
-    MinSpareThreads          5
+    MinSpareThreads          125

ちなみに、正直にいうと$1を${1}にしないといけないことがわからなくて、stackoverflowに質問したところ、数分で回答が来ました。早い。
How to avoid wrong variable name interpretation in perl one-liner - Stack Overflow

ここから先は、上記例を理解するための解説です。

perlでのファイル文字列置換方法を知っていたほうがいい理由

sed
下記のリンク先の通り、sedは同じコマンドでもOSによって挙動の変わることがあります。複数のサーバを管理するのであれば、perlでの置換の方がより広い対象に適用できるので、学習コストを小さく出来ます。
環境に依存しないワンライナーを書くならsedよりperlの方がいい - Qiita

ruby
rubyは、そもそもデフォルトではインストールされていないサーバが多いです。ファイル文字列を置換する方法を覚えるのであれば、perlの方がより多くのサーバで利用出来るので効率的です。

文字列を置換するperlワンライナーの書き方

file1.txtという文字列をバックアップファイルの作成なしで置換する場合は、以下の形式で記述します。(perlコマンドのオプションについては後述)

perl -pi -e 'XXXXXXX' file1.txt

'XXXXXXX'の箇所には、どのように文字列の置換をするのかPerlのプログラムで記述します。's;A;B;g' とすると、Aという文字列をBという文字列で置換させるということになります。sは置換用の演算子を表していて、gが有ると置換対象文字列の該当する文字列を全て置換。gが無いと置換対象文字列の最初に該当する文字列のみ置換となります。また、iをgの位置に一緒に付与すると、大文字と小文字を区別せずに置換するようになります。

gが無い場合は、各行で該当する最初の文字列のみ置換される。

#  echo -e "aabbaabb\naabbaabbaabb" | perl -pe 's;aa;bb;'
bbbbaabb
bbbbaabbaabb

gが有る場合は、各行で該当する文字列全てに対して置換される。

#  echo -e "aabbaabb\naabbaabbaabb" | perl -pe 's;aa;bb;g'
bbbbbbbb
bbbbbbbbbbbb

iが有る場合は、大文字・小文字を区別せずに該当する文字列を置換する。(gが無いので各行の最初に該当する文字列のみ置換)

#  echo -e "AAbbaabb\naabbAAbbaabb" | perl -pe 's;aa;bb;i'
bbbbaabb
bbbbAAbbaabb
最低限覚えておきたいperlコマンドのオプション

以下のオプションは、perlワンライナーで置換するときに知っていた方がよいものです。

-e: 引数に指定した文字列をperlのプログラムと認識する

perl -e "print \"Hello World\n\""
Hello World

-p: ファイルやパイプの入力データに対して、行単位で処理・出力する
各入力行は、$_という変数で表現される。ちなみに、$.は現在行。下記の例では、パイプからの入力データに対して、各行の3番目の文字列をZに置き換えている。

echo -e "aaa\nbbb\nccc\nddd" | perl -pe 'substr($_,2,1,Z)'
aaZ
bbZ
ccZ
ddZ

-i: 入力ファイルの内容を更新して上書きする
このオプションは、-i <ファイル名> とすれば、指定したファイルをperlの処理後の結果で上書きする。-i<拡張子> <ファイル名> とすれば、指定された拡張子つきのバックアップファイルの作成と元ファイルの上書きをする。-iと拡張子の文字列の間にスペースは必要ない。

バックアップファイルを作成しない場合

$ cat sample.txt
aaa
$ perl -pe 's;aaa;bbb;g' -i sample.txt
$ cat sample.txt
bbb

バックアップファイルを作成する場合

$ cat sample2.txt
ccc
$ perl -i.backup -pe 's;ccc;ddd;g' sample2.txt
$ cat sample2.txt
ddd
$ ls -l sample2*
-rw-rw-r--. 1 vagrant vagrant 4 Jan 22 12:33 sample2.txt
-rw-rw-r--. 1 vagrant vagrant 4 Jan 22 12:33 sample2.txt.backup
色々な正規表現

正規表現には種類があります。これを知らないと、perl正規表現を利用した置換をする際、意図した置換にたどり着くのに苦労するかもしれません。

知っておいたほうがいい正規表現の種類は、

です。正規表現で表せる表現幅は、BRE < ERE < Perlの順番で広がっていきます。Perl正規表現は他のソフトウェアでも利用できるように、Perl正規表現を取り入れたPCRE(Perl Compatible Regular Expressions)という汎用ライブラリが作られており、Apache HTTPやPostfixなどで利用されています。

正規表現の違いをgrepコマンドで見ていきます。grep コマンドは、オプションによって利用する正規表現を変更できます。基本正規表現は、-G。拡張正規表現は、-E。Perl正規表現は、-P(Macではこのオプションは無し)です。(オプションの指定なしのデフォルトは、-Gオプションの基本正規表現です。)

実際に、"aという文字列が2個以上3個以下で連続して繋がっている文字列"を正規表現で表すと、BREでは、 a\{2,3\}, EREでは、 a{2,3}となり、BREとEREで正規表現の書き方が異なります。

BREモードでのgrepの動作

echo aa | grep "a\{2,3\}"
aa
echo aa | grep "a{2,3}"
(aaはひっかからない!)

EREモードでのgrepの動作

echo aa | grep -E "a\{2,3\}"
(aaはひっかからない!)
echo aa | grep -E "a{2,3}"
aa

このように、正規表現を書くときにはどの正規表現が利用されるのか意識していないと、意図する文字列が引っかからない可能性があります。

BRE(basic regular expression: 基本正規表現)、ERE(extended regular expression: 拡張正規表現)、Perl正規表現を簡単にまとめると次のようになります。

BRE ERE Perl正規表現 意味
^ ^ ^ 文字列の先頭(行の場合は行の先頭)に一致する。
$ $ $ 文字列の末尾(行の場合は行の行末)に一致する。
∗記号の直前の文字に対する、0回以上の繰り返しに一致する。
\+ + + +記号の直前の文字に対する、1回以上の繰り返しに一致する。
\? ? ? ?記号の直前の文字に対する、0回、もしくは1回の繰り返しに一致する。
\( \) ( ) ( ) ()に囲まれたパターンに一致した文字列を記憶する。記憶した一致文字列には、$0...$9の記号でアクセスできる。
\{m,n\} {m,n} {m,n} {}記号の直前の文字に対する、m回以上・n回以下の繰り返しに一致する。
\{m\} {m} {m} {}記号の直前の文字に対する、m回の繰り返しに一致する。
\{m,\} {m,} {m,} {}記号の直前の文字に対する、m回以上の繰り返しに一致する。

このサイトで、記述した正規表現が意図した通りのパターンか確認できます。pcre(php)というのがPerl正規表現の場合です。
Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript


シングルクウォートで囲むかダブルクウォートで囲むか

perlのプログラムをシングルクウォートで囲んだ場合と、ダブルクウォートで囲んだ場合では動作は変わります。
シングルクウォートで囲まれた文字列は、その文字列のまま解釈されてperlプログラムが実行されます。一方、ダブルクウォートで囲まれた文字列の場合は、変換の必要な文字列を変換してperlプログラムが実行されます。

例えば、以下の例では、"s;$a;$b;g"の箇所が、"s;apple;banana;g"と変換されてからperlのプログラムが実行されています。

a=apple
b=banana
echo "my favorite is apple" | perl -pe "s;$a;$b;g"
test


こちらの例では、"s;$(logname);testuser;g"の箇所が、"s;vagrant;testuser;g"と変換されてからperlのプログラムが実行されています。(lognameコマンドは、現在のユーザのログイン名を表示します。)"s;`logname`;testuser;g"の場合も、"s;vagrant;testuser;g"と変換されています。

id | perl -pe "s;$(logname);testuser;g"
uid=1000(testuser) gid=1000(testuser) groups=1000(testuser) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

id | perl -pe "s;`logname`;testuser;g"
uid=1000(testuser) gid=1000(testuser) groups=1000(testuser) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

このように、ダブルクウォートの内部では、$, `, \ が特別な文字と解釈されます。特別な文字と解釈されないようにするためには、\$, $`, \\というように、特別な文字の前に\を付与します。
ちなみに、シングルクウォートとダブルクウォートで文字列の解釈が異なるのは、perlだからではなくて、bashをシェルとして利用しているからです。このシングルクウォートとダブルクウォートの変換の違いは他のコマンドを利用した時も現れます。このstackoverflowのページには、シングルクウォートとダブルクウォートでの比較がわかりやすくテーブル形式で記載した返答があります。
shell - Difference between single and double quotes in Bash - Stack Overflow


.radioドメインを取得する

タイトルにある通り、昔から.radioドメインが欲しかったのですが、そもそも.radioというトップレベルドメインがつい最近まで存在していませんでした。
しかしながら、最近ついに、念願の.radioトップレベルドメインが登場して個人でも使えるようになった(条件があるけれど)ので申請をしました。申請について、紆余曲折も含めて紹介したいと思います。

このトップレベルドメインである.radioドメインは、欧州放送連合(European Broadcasting Union:EBU)が管理しているそうで、いまのところ日本のドメイン登録の会社(お名前.comなど)では取り扱いされていないようです。
https://www.nic.radio/registrars
上記リンク先に記載されている一覧の会社が、.radioドメインを登録出来るようですが日本の会社はありません。
dotRadio Domains
しょうがないので、上記のregister.radioというところから登録しました。登録費用ですが、結構なお金がかかります。その値段は、250ユーロ。ドルではありません。ユーロです。新規登録に3万円以上かかります。最近人気な.fmドメインで登録は1万円ほどだそうなので、相当な高額ドメインです。
www.hamlife.jp
こちらの記事タイトルでは、30ドル(?)とありますが、それは個人がラジオ放送する用途にサイトを使う場合で、取得できるドメインも(個人名).radioドメインというドメインに制限されるようです。
http://www.nic.radio/launch
僕は別の用途で.radioドメインを使いたかったので250ユーロを払うことになりました。

.radioドメインは、使用用途が制限されているようで、.radioドメインで例えば音楽と関係のないカフェのサイトを作るといったことは出来ないようです。
また、すでにそのドメイン名で実績ある活動をしている組織からの申請をLaunch期間は優先していました。(今はもうgeneral availability期間のようでおそらく早い者勝ちです)

僕の場合も、launch期間に申請していましたが、作りたいサイトは.radioドメインの利用要件に合っているかどうか、ドメインの申請後にメールで連絡が来て追加の聞き取り調査をされました。
その聞き取りメールに返信したのですが、その後は一向に連絡が帰ってきません。申請に落ちた連絡もないしどうなっているのか、2回ほど問い合わせると、2回目の連絡の5分後ぐらいに通過したよという連絡が来て、管理コンソールが使えるようになっていました。
その後、さらに管理コンソールの一部に不具合があったので、再度連絡すると5分後には直っていました。

ちなみに、ドメインの更新料ですが、今のところ僕の登録したところは1年につき25ユーロのようです。(また250ユーロでなくてよかった。)
f:id:ha107chan:20171217120807p:plain

<追記>
.radioドメインの更新料金ですが、年間220ユーロとなっていました。もしかして、最初の25ユーロは運営が間違えて登録していたのかもしれません。。とにかくこの.radioドメインは維持費用が高い。

f:id:ha107chan:20190211214926p:plain
radioドメイン更新費用


日本からこの.radioドメインを利用したいという人が果たして、どの程度存在するのか謎ですが、他の.radioドメインをこれから利用したい人向けに参考となるように書きました。