TORIPIYO DIARY

recent event, IoT, programming, infrastructure topics

英語の文章を読む必要性

直接技術の話ではないですが、昨日、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のページには、シングルクウォートとダブルクウォートでの比較がわかりやすくテーブル形式で記載した返答があります。
linux - 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ドメインを利用したいという人が果たして、どの程度存在するのか謎ですが、他の.radioドメインをこれから利用したい人向けに参考となるように書きました。

raspberry piでend Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000bというエラーメッセージが表示された時に対応したこと

raspberry pi 3を家で動かしていたら、いつの間にかハングして停止していました。いつもは電源プラグを外して差し込み直せば正常に起動するのですが、今回は電源プラグを差し込み直しても起動しません。。。
仕方がないので、キーボード・マウス・ディスプレイをraspberry piに繋いでコンソール接続すると下記のように起動時にエラーメッセージを吐き出していました。
f:id:ha107chan:20171111221026j:plain

一番下のエラーメッセージをみると、"end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b"と表示されています。
f:id:ha107chan:20171111221033j:plain

このメッセージをグーグルで調べてみると、どうやらSDカードが問題を起こしている可能性が高そうです。いくつかのサイトでは、新しくSDカードを購入して新しいOSイメージを入れてraspberry piに接続したら正常に動いたと書いてあります。
ただ、これまでOSに設定してきた内容を無にしたくない!と思い、さらに調べてみると、別OSでmicroSDをマウントしてfsckをかける方法を試している人がいます。
blog.hahasoha.net

自分もこの方法を試そうかなと思いながらも、さらに調べると、raspberry piにコンソール接続しているときに、キーボードとマウスを外して起動し直すと正常に起動したという話を見つけました。
そんなバカなと思いながらも、キーボードとマウスを外して起動し直すと無事に起動されましたw

もしかしたら、キーボードとマウスは関係なくて、たまたまうまく起動できる時もあるということなのかもしれませんが、fsckせずに動くようになったのでしばらくはこの方法で復旧をさせようと思います。

macOSをHighSierraにアップグレードする

特に今のSierraで困っているわけではないですが、新しいファイルシステムであるApple File System(APFS)を試してみたくて、プライベートのMacをHigh Sierraにアップデートしてみました。更新のお知らせが来ないので、App StoreからHigh Sierraを探してインストーラをダウンロードしました。

インストーラのサイズは4.8GBほどです。インストール時間は自分の2017年MacBook Pro 13inchではインストーラを起動してから1時間弱ほどでした。インストールの最中にプロンプトが表示されていつも色々と選択していたような気がするのですが、今回のHigh Sierraのアップデート中には特にそれはありませんでした。

アップデート中にお風呂に入って戻ってくるとなぜか画面が真っ暗になっていて、インストールに失敗したと思ったのですが、強制再起動をかけると何事もなくすんなり起動してHigh Sierraになっていました。今までのMacのOSアップデートの中で一番更新された感じがしないアップデートです。
homebrew, atom, docker for macなど普段僕が利用しているものも問題なく動きました。

mountコマンドなどを叩くと、apfsファイルシステムでマウントされているのがわかります。

 ~: mount | grep apfs
/dev/disk1s1 on / (apfs, local, journaled)


SierraとHighSierraでいくつかファイルシステムに関係ありそうなところのパフォーマンスを比較したので記載します。利用しているマシンは、MacBookPro 13inch 2017 cpu3.1GHz, memory16GBです。

duコマンドを使って/Usersディレクトリ内のサイズを調べる
  • なんか、HighSierraのほうが遅くなっていますね。

Sierra

~: time du -hs /Users
 85G	/Users
du -hs /Users  0.74s user 11.22s system 62% cpu 19.291 total

High Sierra

~: time du -hs /Users
 84G	/Users
du -hs /Users  0.93s user 20.31s system 56% cpu 37.771 total
ddコマンドを使って10GBのファイルを作成する
  • これも、HighSierraのほうが遅くなっています。。。。これでは、LowSierra?

Sierra

~: time dd if=/dev/zero of=testfile bs=1024 count=10240000
10240000+0 records in
10240000+0 records out
10485760000 bytes transferred in 29.404851 secs (356599665 bytes/sec)
dd if=/dev/zero of=testfile bs=1024 count=10240000  2.05s user 23.27s system 86% cpu 29.410 total

High Sierra

~/Downloads: time dd if=/dev/zero of=testfile bs=1024 count=10240000
10240000+0 records in
10240000+0 records out
10485760000 bytes transferred in 108.594898 secs (96558496 bytes/sec)
dd if=/dev/zero of=testfile bs=1024 count=10240000  2.19s user 101.00s system 95% cpu 1:48.61 total
Blackmagic Disk Speed Testを使ってディスクパフォーマンスを比較する
  • 数値を見ると、High Sierraのほうが、各ビデオフォーマットに対する読み込み・書き込みの速度は早くなっているようです。

Sierra
f:id:ha107chan:20171106205401p:plain

High Sierra
f:id:ha107chan:20171106205436p:plain


なぜduコマンドやddコマンドのパフォーマンスは低下したのに、Blackmagic Disk Speed Testの結果は良くなったのか、はっきりした理由は自分にはわかりません。。。
いずれにしよ、HighSierraにしても体感で感じられるぐらい使用心地が極端に悪くなったりはしませんでした。

macでファイルを削除してもディスクユーティリティにPurgeableと表示されてディスクの使用量が減らないときの対処法

vagrant仮想マシンをたくさん作成していたら、いつのまにかmacbook proのディスク使用量が90%を超えてきたので、不要なvagrantデータを60GBほど削除させました。しかし、df -hで使用量を調べても使用量が減っていません。disk utilityを開いてみてみるとPurgeableというものが表示されていて、df -hの結果は、Purgeableのデータサイズも入れた結果となっているようです。

f:id:ha107chan:20170923184434p:plain

少し調べると、Purgeableというのは、MacOS Sierraから導入された機能だそうで、パージ可能だと判断されるファイルは、"必要時に常にダウンロードが可能なもの"だそうです。
support.apple.com

このページを見ると、iCloud Drive, iCould, iTunesのデータなどがPurgeableに該当するそうですが、自分はどれも全然利用していません。。。
support.apple.com

何か別のものがPurgeableのデータとして認識されているのではないかと思い調べて見ると、time machineのローカルにあるsnapshotが、Purgeableのデータとして認識されているのではないかと言っているページにたどり着きました。この現象は、Appleのサポートに聞いても原因がなかなか特定できなかったようです。
forums.developer.apple.com

I simply opened Time Machine Preferences, clicked the Lock Icon to unlock and make changes. Then I unchecked the box next to Back Up Automatically under the TM Icon. Finally I restarted my Mac. When I turned my Mac back on to check the storage all the purgeable data was gone which freed up over 70 GB on my SSD. Afterwards I went back into the TM preferences and rechecked the Back Up Automatically box. After restarting my computer a second time I saw that the purgeable data was still gone.

time machineで直近のバックアップを取った後、上記記載の通りtime machineの設定ページで、"Back Up Automatically"のチェックボックスをまず外してmacを再起動させます。そして、再起動後のmacを見ると確かにPurgeableの領域は減っていました。(ゼロにはなっていないけど、だいぶ減ったのでしばらく様子を見たいと思います。もしかしたら本当にiCloud Drive, iCould, iTunesのデータかもしれない。。)

f:id:ha107chan:20170923190750p:plain

再起動後のmacで、再びtime machineの設定ページを開いて"Back Up Automatically"のチェックボックスにチェックを入れてまたmacを再起動してもPurgeableのデータサイズが再び戻っているということはありませんでした。以上、他の困っている人の参考に。