OmniAICreator/Qiita-1.07M huggingface dataset:
WordPressの脆弱性 CVE-2019-17671 についてのメモ

#はじめに
WordPress 5.2.4のリリースノートを読んでいたら気になった項目があったので調べてみた。そのうち誰か記事にするだろうと思っていたけど、日本語での解説が今も見あたらないので当時のメモを元に記述。

#脆弱性の概要
[WordPress 5.2.4のリリースノート](https://wordpress.org/news/2019/10/wordpress-5-2-4-security-release/)を見ると、

> Props to J.D. Grimes who found and disclosed a method of viewing unauthenticated posts.

とある。

該当するCVE情報について調べると、この脆弱性には[CVE-2019-17671](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17671)という識別番号が振られていることがわかる。こちらでは

> In WordPress before 5.2.4, unauthenticated viewing of certain content is possible because the static query property is mishandled. 

と記述されている。
簡単に言えば「非公開の記事が認証無しで閲覧可能な不具合がある」ということらしい。

#脆弱性の影響範囲
脆弱性が利用できるのが限定的な条件下であれば、それほど重大では無いと思われるので、実際にどのような場合に影響を受けるのか確認してみる。

なお、詳細な解説は下記リンク先に記述されているため、ここでは省略。
https://0day.work/proof-of-concept-for-wordpress-5-2-3-viewing-unauthenticated-posts/

WordPress 5.2.3で確認した結果、以下のとおりになった。

- URLに特定のパラメータ`?static=1&order=desc`を付与することで、通常は閲覧できない内容が表示されてしまう。
- 表示されるのは非公開および下書きの固定ページ。
- パスワード保護されたページについては、ページが存在すること自体は分かるが内容は閲覧できない。
- 投稿は本脆弱性の影響を受けない。

下書きを見られて恥ずかしい思いをするくらいで済むか、後日公表予定のニュースリリースが漏れて問題になるかはサイト次第だろうが、対策をした方が良さそうに思える。

#ワークアラウンド
WordPressをアップデートすることが一番だが、事情によりアップデートすることが難しい場合はGitHubの[修正履歴](https://github.com/WordPress/WordPress/commit/f82ed753cf00329a5e41f2cb6dc521085136f308)を参考にパッチを当てることで対応可能になる。
アンケートシステムでif文学んだ

#前回のあらすじ
・ローカル鯖構築（XAMPP3.2.4にて）
・前のページからデータを受け取る作業を学んだ
・if文で入力に不備があったらお知らせ文を表示させてみた
#今日やったこと
・if文を利用して、アンケートに空欄があったら進むボタンが表示できない設定にした
・history.backを使って戻るボタンを作成したら、入力した内容を記憶させたまま入力フォームに戻ることができた
（参考教科書『いきなりはじめるPHP　ワクワク・ドキドキの入門教室』)
#感想
if文って便利！入力する項目が多くなったら、フラグ制御というものを使うらしいけど・・・後々学べるのかしら

#次回の目標
引き続き、入力するプログラムをしっかり見つつ、理解していこう
Gatsby.js + NetlifyCMS における画像関連エラー

# エラーについて
Gatsby.js + NetlifyCMS において、管理画面からマークダウンで記事を更新後、以下のようなエラーがでた。

```bash
 Error: Field "image" must not have a selection since type "String" has no subfields.
```


# エラーの原因について
NetlifyCMS側が勝手に画像を相対パスから絶対パスに直すため。
相対パスを使うGatsbyとは相性が悪い。

以下は期待したいマークダウンの出力

```markdown
---
title: 元旦だから今年の目標を決めたい。
layout: post
author: User
date: 2020-01-01T11:00:00.000Z
draft: false
tags:
  - Etc
image: img/newyear.jpg
---
とりあえず新年最初に……

```

……そして以下はNetlifyCMSを利用の画像選択を利用したときの期待していなかった出力。

```markdown
---
title: 元旦だから今年の目標を決めたい。
layout: post
author: User
date: 2020-01-01T11:00:00.000Z
draft: false
tags:
  - Etc
image: /img/newyear.jpg      
---
とりあえず新年最初に……

```

`image`が`/img/newyear.jpg `となっているため、件のエラーが出る。


# エラー解消に参考にしたサイト
[Cool image loading with Gatsby.js v2 and Netlify CMS v2](https://blog.rousek.name/2018/08/10/cool-image-loading-with-gatsbyjs-v2-and-netlify-cms-v2/)

とりあえず上記サイトで解決できた人もいるのですが、自分の場合これだけではうまく行かず。
おそらく'gatsby-source-filesystem'で画像パスを操作する必要もあるようです。


まず'gatsby-plugin-netlify-cms'はプラグイン配列の最後に置いて、以下をプラグインに追加

```javascript:gatsby-config.js
  plugins: [
//省略
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/static/img`,
        name: 'images',
      },
    },
//省略
    'gatsby-plugin-netlify-cms',
  ],
```

おとなしく画像アップロードフォルダはstatic/imgに固定しておきます。

```yaml:config.yml
backend:
  name: git-gateway
  branch: master

media_folder: static/img
public_folder: /img

##### 省略

    fields:
      - { label: "Title", name: "title", widget: "string" }
      - { label: "Publish Date", name: "date", widget: "datetime" }
      - {label: "Draft", name: "draft", widget: "boolean", default: false}

      - label: "Image"
        name: "image"
        widget: "image"
        default: ""
        media_library:
          config:
            multiple: true

```


細かいファイル構成などは先程の方のGitHubに詳しい。こちらも参考にしてください。
[Liduska/personal-blog](https://github.com/Liduska/personal-blog)

かっこいい
そしい軽い！(今の所！)
cscの作法

#概要

cscの作法、調べてみた。

#環境

.NET Framework 2,0

#写真


![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/fc679f24-55a2-8e24-3c12-867caae367b5.png)

#サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	form1() {
		Text = "hello";
		ClientSize = new Size(200, 200);
		Label la1 = new Label();
		la1.Location = new Point(50, 50);
		la1.Text = "Hello World!";
		Controls.AddRange(new Control[] {
			la1
		});
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}

```

#コンパイル

```
csc test.cs
```

以上。
html  favicon / 箇条書き

#htmlとcssでとりあえず覚えたいやつ書き出し①

#### faviconを作る
[favicon作成](https://www.favicon.cc/)
#### faviconを追加
```index.html
<head>
<!-- 同階層にfavicon.ico置く -->
<link rel="icon" href="favicon.ico">
</head>
```
#### cssを外部ファイルに書く

```index.html
<head>
<link rel=“stylesheet” href=“style.css”>
</head>
```
#### 箇条書き
```index.html
<!-- 箇条書きを作る -->
<body>
<ul>
    <li>リストA</li>
    <li>リスB</li>
    <li>リストC</li>
</ul>
</body>
```
#### 箇条書きのマーカー消す
```style.css

ul {list-style: none;}

/* ※li要素に対しても有効   */
```
QuiverでWebサイトの内容をMarkdownとしてクリップする

# はじめに

[Quiver](https://apps.apple.com/jp/app/quiver-take-better-notes/id866773894?mt=12)はMarkdownでメモを書くことができる有料のMacアプリです。

このQuiverが提供する[Quiver Web Clipper](https://chrome.google.com/webstore/detail/quiver-web-clipper/hcnffmpopoelpggikahccdfenoobjigj)のChrome拡張を使用すると、Webサイト全体の内容や一部の箇所をMarkdownとしてQuiverアプリにクリップすることができます。

# 前提
Quiver Web ClipperはQuiver v3.2.4以上で動作します。

# クリップ方法

* Quiverの[Macアプリ](https://apps.apple.com/jp/app/quiver-take-better-notes/id866773894?mt=12)をインストールします。
* Quiver Web Clipperの[Chrome拡張](https://chrome.google.com/webstore/detail/quiver-web-clipper/hcnffmpopoelpggikahccdfenoobjigj)をインストールします。
* 任意のWebサイトにChromeのブラウザで遷移します。
* Webサイト全体の内容をMarkdownとして取り込む場合
    * Chromeのツールバー上の```Quiver Web Clipper```のアイコンを選択します。
    * その後、右側にある```Quiver```アイコンを選択します。
    * 選択後、Quiverアプリにクリップされます。
* Webサイトの一部の箇所をMarkdownとして取り込む場合
    * 任意の箇所を範囲選択し、右クリックなどでコンテキストメニューを開きます。
    * コンテキストメニューの```Clip to Quiver``` > ```As Markdown```を選択します。
    * 選択後、Quiverアプリにクリップされます。

# さいごに

Webサイトで情報収集や調査を行う際に、```Quiver Web Clipper```を使うと便利かと思います。
自宅サーバーを建てる上でのお金の不安と解決策

##なぜサーバー建てるの？
クラウドサーバー全盛の現代で、なぜ自宅サーバーを建てようと思ったかのきっかけについて書きます。

最近、転職をして周りにバリバリコードかける人のいる環境にきたはいいものの、中々その人たちの会話について行けずモヤモヤと過ごしていました。
そんな時に、上司から「自宅サーバー建ててみると結構勉強になるよ」と言われたんです。

「サーバーなんて自分で作れるんか、、」と率直に疑問だったんですが、できるらしい。
と言うことで、特に大きな理由はなく「勉強のため」に自宅サーバーを建ててみようと思いました（笑）
（大した理由でなくてすみません。。）

###目標は？
今回は、あくまで「勉強のため」なので「安くて速くサーバーを建てる」ことを目標に頑張っていこうと思います。
ですので、以下の記事を参考にしつつ、簡単、もしくは安くできるところはアレンジして進めていきます。

[とある自社・自宅サーバーの建て方:超かんたん概要（リンク）](https://qiita.com/akinko/items/dbfb5926f43a003cffbf)

この記事を読んで、「結構簡単にできそうだぞ！」と言う自信が湧いた一方で、「お金そこそこかかりそうだな、、」という不安が芽生えました。

この記事では、サーバーを建てるための前準備（OSインストールの前あたり）までを書いていきますが、その中でもお金に関する疑問と解決策を中心に書いていきます。

##サーバー建てる上での疑問と不安（主にお金面）

###高価なハード必要なの？
自宅サーバーを建てることについて色々調べるとやはりハードを揃えるのが大変そうだなという印象でした。


####サーバーに採用するハードに必要な要素
サーバーに採用できるデバイスはそんな特別な性能がいるわけではないようです。ノートパソコンでも全然できる。
一点非常に大事な機能がサーバー用のハードには求められるそうです。それは、冷却機能（排熱機能）。
注意しないと本体の発熱が酷くなってしまい最悪発火してしまうケースもあるんだそうです...。

僕も下で紹介してる記事を読んで、かなり怖くなりました。
[ノートPCをサーバーにして大惨事になった話(リンク)](http://www.hotel-raj.si/hr)

**理由**
冷却機能（排熱機能）が重要な理由としては大きく2点
①ホコリがたまりやすい
すごく単純ですが、これは結構問題らしいです。自宅のノートパソコンってほったらかしにしておいてホコリ被ってたりしませんか？
人が住んでるからホコリでるのは当たり前なんですが、発熱しているハードにホコリが入ってしまうとやはり発火に繋がってしまうそうです。

②そもそもノートパソコンはサーバー用に作られていない
身も蓋もないようですが、事実のようです。具体的に言うと、ノートパソコンは24時間稼働を前提に作られていない。
サーバーは24時間稼働していることが運用上求められるじゃないですか？スマホゲームで「サーバーメンテナンスでアクセスできません」ってなるとイライラすると思うんですが、あれって裏を返せば、メンテナンス中以外は24時間稼働し続けているわけですよね。クライアントからリクエスト入れた時にいつでもレスポンスしてくれないといけないのがサーバーの宿命という訳です。

一方のノートパソコンは使い手が開いた時だけ動いていればいいですよね？何かインストールとかしてる時じゃない限り、本体閉じて電源を切ってても問題ない。ここの使われ方の違いからそもそも仕様が違うそうです。

####今回採用したハードは?
1番安く済ませるため、自宅の押入れに眠っていた2011年頃に作られたSONYのVAIOを使ってサーバーにしていきたいと思います。
OSがWindows7でCPUがintelのCeleronであるため中々不安要素の多いハードですが、まぁ練習ということで目をつむりたいと思います。冷却機能（排熱機能）の性能も特別なものではないと思うのですが、24時間稼働させないで練習用にという限定的な用途として使うのでまぁよしとします。


###IPアドレスは固定IPを申し込まないとだめ？
もう１つ気になったのが、利用する回線の問題です。

自分の家には回線を引いているのですが、固定IPではありません。
結構いろんな記事を読むと、「サーバー建てるなら、固定IPにしたほうがいい」と言う意見多かったです。
一般的には申し込まないとIPは変動し続けてしまうそうです。

しかし、IPを固定にする申し込みにはお金がかかります。それを避けられないかと色々な方法を探ってみました。

そしたら、そんな都合のいい方法が見つかりました！

####DDNS(ダイナミックDNS)
まず、DNS(ドメインネームシステム)とは何ぞやと言いますと、Wikipediaによると「動的に割り当てられるIPアドレスと、そのホスト名の対応を、動的に登録・管理する仕組み」だそうです。

そして、上記したように変動してしまうIPアドレスを定期的に受け取って、１つのドメインとして固定的にまとめるシステムがDDNSという感じだそうです。
DDNSを利用するのはとても簡単で、MyDNS.jpを使います。
コチラ、無料です！

[MyDNS.jp（リンク）](https://www.mydns.jp/)

コチラに登録して、その後に自分の使っているルーターのIPアドレスを定期的にMyDNS.jpに通知していくことが必要です。
その定期通知によって、「あ、このIPアドレスは前のIPと送られてきてる所が一緒だな」と DDNSが理解してくれます。そうすることで、変わってしまう IPを１つのDDNSにまとめることができるそうです。
申し込みや定期通知のやり方は、下の記事がとても分かりやすいです。

[DDNS で自宅サーバーに独自ドメイン(リンク)](https://imoni.net/tips/00xx/0010.html)

##振り返り
今回はサーバーを建てようとしたキッカケや目標、そしてサーバーを建てる上でお安くできるポイントをいくつか紹介していきました！

まだ、全部完成しているわけではないのですが、いわゆる「自鯖」を構築できるよう頑張ります。
WSLのPATHからWindows側のPATHを除外する

## 参考

https://devblogs.microsoft.com/commandline/automatically-configuring-wsl/

## 手順

① /etc/wsl.conf を作成または編集する。

```bash
cat << EOL | sudo tee /etc/wsl.conf
[interop]
appendWindowsPath = false
EOL
```

② wslを再起動する。
③ うまくいかない場合は、コマンドプロンプトから `wsl --shutdown` してからもう一度wslを起動する
④ そのほかの設定は https://devblogs.microsoft.com/commandline/automatically-configuring-wsl/ などを参照。

---

WSL / WSL2における対話コンソール上でコマンドのタブ補完をしようとすると、もっさりとした動作で快適とはいいがたい場合があります。
もっさりの原因の一つと考えられるのが、WSLのPATH環境変数に、Windows側の実行ファイルパスが追加されてしまっていることです。

以下が私の環境(Windows10 Insiders Preview のビルド2004)でPATH環境変数を表示した例です。

```
$ echo $PATH
/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Program Files (x86)/Intel/iCLS Client/:/mnt/c/Program Files/Intel/iCLS Client/:/mnt/c/WINDOWS/system32:/mnt/c/WINDOWS:/mnt/c/WINDOWS/System32/Wbem:/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/:/mnt/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/DAL:/mnt/c/Program Files/Intel/Intel(R) Management Engine Components/DAL:/mnt/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/IPT:/mnt/c/Program Files/Intel/Intel(R) Management Engine Components/IPT:/mnt/c/WINDOWS/System32/OpenSSH/:/mnt/c/Program Files/Git/cmd:/mnt/c/Program Files/Git/mingw64/bin:/mnt/c/Program Files/Git/usr/bin:/mnt/c/Program Files/Microsoft SQL Server/130/Tools/Binn/:/mnt/c/Program Files/PuTTY/:/mnt/c/Go/bin:/mnt/c/ProgramData/chocolatey/bin:/mnt/c/HashiCorp/Vagrant/bin:/mnt/c/Program Files/dotnet/:/mnt/c/Program Files/Microsoft SQL Server/Client SDK/ODBC/170/Tools/Binn/:/mnt/c/Program Files/nodejs/:/mnt/c/Program Files/Intel/WiFi/bin/:/mnt/c/Program Files/Common Files/Intel/WirelessCommon/:/mnt/c/Users/abcku/.windows-build-tools/python27/:/mnt/c/Program Files/nodejs/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/mnt/c/Users/abcku/AppData/Roaming/npm/node_modules/windows-build-tools/node_modules/.bin:/mnt/c/Users/abcku/AppData/Roaming/npm/node_modules/.bin:/mnt/c/Users/abcku/work/edex-ui/node_modules/.bin:/mnt/c/Users/abcku/AppData/Local/Microsoft/WindowsApps:/mnt/c/Program Files/Docker Toolbox:/mnt/c/Users/abcku/AppData/Local/atom/bin:/mnt/c/Program Files/Git:/mnt/c/Program Files/Microsoft VS Code/bin:/mnt/c/Users/abcku/AppData/Roaming/npm:/mnt/c/Users/abcku/go/bin:/mnt/c/Users/abcku/AppData/Local/Programs/Microsoft VS Code/bin:/mnt/c/MinGW/bin:/home/kotaro/.fzf/bin:/home/linuxbrew/.linuxbrew/bin
```

`/mnt/c/` からはじまるパスが大量に含まれていることがわかります。
これにより、補完候補の探索に必要以上の時間がかかってしまっています。


WSL側からWindowsコマンドを頻繁に利用するのでなければ、Windows側のパスは不要といえます。

冒頭の手順を実施すると、以下のようにPATHが変化しました。

```
$ cat << EOL | sudo tee /etc/wsl.conf
> [interop]
> appendWindowsPath = false
> EOL
[sudo] password for kotaro:
[interop]
appendWindowsPath = false
$ exit
logout

C:\Users\taro3>wsl --shutdown
```

```
C:\Users\taro3>wsl
$ echo $PATH
/home/kotaro/.local/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/linuxbrew/.linuxbrew/bin:/home/kotaro/.fzf/bin
```

よいWSLライフを！
Automation Anywhere BYOLでAWS上にControl Roomを立ててみる

少し前にAWS(Amazon Web Services)のMarketplace上に、Automation Anywhere BYOLが掲載されていたので、今回、試してみました。

ちなみに、BYOLとは、Bring Your Own Licenseの略で、あるパッケージソフトウェアのライセンスを持っていれば、クラウド側ですぐに使えるような仕組みです。
今回の例の場合は、AWS上でAutomation AnywhereのControl Room(サーバー)や、Clientをユーザー側でインストールしなくても、最初からインストール済みの仮想マシンが作れるようになった。という事です。

もし実際に試す場合には、AWSのEC2という、仮想マシンを作成・運用出来る有料のサービスを利用します。
利用料が立てる仮想マシンのスペックにより変動しますので、ご注意ください。

なお、筆者はAWS初心者ですので、AWSの設定、特にセキュリティ周りは各自充分に調査の上運用してください。

#手順
1. AWSの利用を開始する。→ この辺りはググれば色々出てくると思います。
2. AWS Marketplaceにアクセスし、[AWS Marketplace: Automation Anywhere BYOL](https://aws.amazon.com/marketplace/pp/Automation-Anywhere-Inc-Automation-Anywhere-BYOL/B081P8XLB4)をSubscribeする。
3. 右側に出る、Continue to Configurationのボタンを押す。
4. Fulfillment Option、Version、インスタンスを作成するリージョンを選んで、Continue to Launchを押す。
5. 各メニューよりオプションを選択し、Launchを押す。
6. AWS マネジメントコンソールよりEC2を開く。
7. 左側のメニューより、「セキュリティグループ」を開く。
8. Automation Anywhere BYOL-11-3-3-というような名前のグループが出来ているので、インバウンドの設定をする。
リモートデスクトップの3389, Control Roomとの接続に使う943, 4530を開ける。（いずれもプロトコルはTCP）
その他、必要なポートを開ける。
私は[AWSの歩き方(EC2→IE接続まで) - Qiita](https://qiita.com/manchan/items/8a8d4d7529bf06be5326)を参考にしました。
9. EC2のページの左側のメニューより、「インスタンス」を開く。
10. 作成されたインスタンスを選択し、アクションより、「接続」を押す。案内に従ってリモートデスクトップ接続をする。
11. リモートデスクトップで接続したインスタンスで、適当なWebページを開いて、インターネットに接続されていることを確認する。
12. Windows DefenderのFirewallをOffにする。（AWS外部からControl Roomに接続する場合。AWSのセキュリティグループ設定によりFirewallと同等のセキュリティが確立されているため、Windows Defenderを切ってしまう例が多いです。）
13. WindowsのServiceツールより、Control Room関係のServiceを全て立ち上げる。
（必要なServiceはAutomation Anywhere BYOLのUsageの欄に記載されています。）
14. しばらくしてからデスクトップ上にある、Control Roomのアイコンをクリックし、初期設定を行う。
15. セットアップ完了！！

![2019-12-31 20.49のイメージ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/fa3c1588-f890-b752-3962-7b73f7d32d0b.jpeg)


#注意事項：
- Control Roomの動いているインスタンスが稼働し続ける限り課金が発生しますので、デモ目的で立ち上げる場合は、使用しない間はインスタンスを停止しておきましょう。
- Control Roomのサービスを立ち上げた直後にアクセスすると、「Bad Gateway」と出る事がありますが、まだControl Roomが立ち上がりきっていませんので、もう少し待ってから再度トライしてみてください。
- Automation Anywhere BYOLによって作られたインスタンスは、Control Room関係のServiceが全てDisabledとなった状態ですので、WindowsのServicesツールより必要なServiceを全て立ち上げてください。必要となるServiceの一覧はAWS MarketplaceのAutomation Anywhere BYOLのUsageの欄に記載があります。
- 必要に応じてElastic IPの設定も行ってください。
- Automation Anywhere BYOLで作成されるイメージにはClientも入っていますので、Bot Creator, Bot Runnerの環境を構築するのにも使えます。
- Clientとして設定する場合は、Control RoomのServiceは止めたままで大丈夫です。
- 2020/1/1現在、提供されるAutomation Anywhere Enterpriseのバージョンは11.3.3です。
Realmのデータを確認するツール・ライブラリまとめ

Androidアプリの開発中、Realmに書き込んだデータを確認しようとしたのですが、
色々あってどれを使うかめちゃくちゃ迷ったので、調べたことをまとめておきます。
（間違いなどあればご指摘お願いします:pray:）

# Realm Studio
## 概要 :pencil:
* Realmが公式に提供している開発者ツール
  * 公式ドキュメント: https://realm.io/docs/javascript/latest/#realm-studio
* 公式サイト: https://realm.io/products/realm-studio/
* `Realm Database`と`Realm Platform`を簡単に操作することができる
* 2017年10月頃にリリースされた
* Mac, Windows, Linuxに対応している

<img width="811" alt="スクリーンショット 2020-01-01 17.45.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112818/27ad0759-bc09-47c4-e39b-820cda26eb71.png">

## 使い方 :pick:
adbコマンドを使って`.realm`ファイルを取り出し、アプリケーション上で開いてデータを確認する。

## 所感 :information_desk_person:
Realmが2017年以降力を入れて開発しているサービスっぽい。
できることの幅も広く、Realm Browserの昇華版と言えそう。

# Realm Browser
## 概要 :pencil:
* Realmが公式に提供している開発者ツール
  * 公式ドキュメント: https://realm.io/jp/docs/java/latest/#realm-browser
* Mac App Store: https://apps.apple.com/app/realm-browser/id1007457278
* `.realm`データベースを閲覧、編集することができる
* Mac専用

<img width="810" alt="スクリーンショット 2020-01-01 17.45.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112818/35e38726-07cb-9a9f-b54e-f01e6e7b3482.png">

## 使い方 :pick:
adbコマンドを使って`.realm`ファイルを取り出し、アプリケーション上で開いてデータを確認する。

## 所感 :information_desk_person:
2017年でアップデートが終わっているので、今後もうメンテされることはなさそう？
今から使うのならRealm Studioを選びたい気がする。

# stetho-realm
## 概要 :pencil:
* Stethoは、Chrome Developer Toolsを利用して、Chromeからデバッグを行うことができるAndroidのデバッグブリッジ
  * Stethoの公式サイト: http://facebook.github.io/stetho/
  * Facebookが作っている
* stetho-realmは、StethoをRealmに対応したライブラリ
* GitHub: https://github.com/uPhyca/stetho-realm
* 2017年を最後に更新されていないが、その後もコミュニティによって対応がされているらしい
* 個人が作っている

<img width="1062" alt="スクリーンショット 2020-01-03 19.48.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112818/5b2d8811-118a-3e72-03d9-71af6e50e44f.png">


## 使い方 :pick:
build.gradleに依存関係を追加し、Application内で初期化、
アプリを起動後、Chrome上でデータを確認する。

## 所感 :information_desk_person:
個人的には一番簡単で、使いやすいと感じた（新たにアプリケーションをインストールしたり、adbコマンドを叩いたりする必要がないため）。
一点注意点としては、Realm3.7.1以上のバージョンはサポートされておらず、Realmの最新版を使ったりするとアプリがクラッシュするので、下記記事を参考にコミュニティが対応しているリポジトリを使う必要がある。
https://blog.local-c.com/archives/2496
https://stackoverflow.com/a/51381971/11934352

# realm-browser
## 概要 :pencil:
* Androidデバイス上でデータベースを閲覧するライブラリ
* GitHub: https://github.com/dmytrodanylyk/realm-browser
* 2015年で正式にサポートが打ち切られている
* 個人が作っている

<img width="753" alt="スクリーンショット 2020-01-01 18.05.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112818/e96e207b-ba04-1acf-18ba-037de9dad557.png">

## 使い方 :pick:
build.gradleに依存関係を追加し、初期化、
閲覧用のActivityを呼び出して、デバイス上でデータを確認する。

## 所感 :information_desk_person:
デバイス上で見れるのは楽そうでいいなと思うが、参考になる記事も少ないので、ハマったときにつらそう。

# 結論
* さくっと確認するなら **stetho-realm** が一番使いやすいと感じた（→結果これを使った）
* これからRealm公式ツールを使うなら、Realmが推している **Realm Studio** を使いたい
【Nuxt.js】SEO基礎編②：超簡単解説！5分でわかるSEO

前置き

前回の続きです。
全てにおいて
https://note.com/aliz/n/nf7cfce1bb6ca
**心構え**
が大事になるので、ご確認を。



# 3-2.SEO内部対策


使いやすいサイトを作ること
**ページ内の質をあげることです。**
知りたい情報で検索をし、
たどり着いた先で
良質な情報が得られることが求められます！

なぜこれが重要なのかは
基礎編をご覧ください。
クローラー、インデクサ、インデックスなど

**具体的な対策方法は2つ
・インデクサビリティの最適化
・クローラビリティの最適化**

## インデクサビリティの最適化

クローラーに適切に情報を
インデックスしてもらうために
分かりやすいサイト構造に
**どのページにどの情報があるかを判別させる**
具体的なポイントを下記で説明します。

**大枠の構造が…
・パンくずリストの設置
・title要素の最適化
・meta要素の最適化**
など
細かいpタグなどは別記事にて。

ページネーションは
サポート終了したため触れません。
複数のページ情報を
1連のまとまりのあるものと判別するために
rel=”next”とrel=”prev”を使用していました。
それを判別しなくなったということですね。
https://webmaster-ja.googleblog.com/2011/12/relnext-relprev.html


### 3-2-1.パンくずリストの設置🍞
<img width="624" alt="Frame 1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/a92adff1-9970-30ce-cd79-572b467f2afb.png">
ページ上部によくあるこれ、
クローラーが今どこにいて
どんな情報が得られるのか
判別しやすくなります👀
多くても3階層くらいが良さそうです。

### 3-2-2.title要素の最適化

**そのページの情報を簡潔に表す言葉のため非常に重要です！**
**・見出しタグにキーワードを入れる**
　h1〜h6の中でも
　h1にはしっかりと
　検索されるキーワードを入れましょう！
　でもいくつも盛り込めないので、
　ターゲットを絞って選定🍀
　尚且つ、タイトルだけで内容が想定でき、
　想定通りの情報が書かれていることが◎✨
　前回の記事
　**3-1-1.検索キーワードを選定**
　で選定したキーワードを入れましょう。

**・h1はページに1つ！**
　それ以外はいくつ使用してもOKです！
　section内にh1を1つずつの場合、
　ペナルティはないけど
　原則ページに対して1つが良さそうです。

**・h1〜h6の構造を守る**
　h1の下にh3がきたりとかダメ

**・文字数は30文字程度に**
　検索表示結果で表示される字数がこれくらいだから

### 3-2-3.meta descriptionの最適化

ページの説明文にあたる部分です。
検索した時にタイトルの下に出るあれです。
要約文をスペニットして表示させています。
検索順位には、
あまり影響がないと言われていますが、
クリック率に影響があります。

・選定したキーワードを盛り込む
・文字数はスマホ50文字程度、PC120文字程度
ただし、
設定した文通りに
スペニットされるわけではない
というのが難しいところですね。
こちらのサイトが参考になります！
https://digital-marketing.jp/seo/what-is-a-description/#i

### 3-2-4.meta content="noindex"の最適化

基礎編でやった
**2-2.インデックス**
これをインデックスさせないことです。
これを活用して、
現在低品質なページをnoindexにし、
良質なページの割合を増やして
評価をあげることができます🍒
インデックスされているかどうかは
GoogleSearchConsoleで確認ができます🌟
https://search.google.com/search-console/welcome

noindexについては
ここが参考になります！
https://seolaboratory.jp/91446/






**このアカウントでは
Nuxt.js、Vue.jsを誰でも分かるよう、
超簡単に解説しています🎈😀
これからも発信していくので、
ぜひフォローしてください♪**
https://twitter.com/aLizlab
[WIP] gRPCの中身ってどんな？feat. Go

## はじめに

Goが大好きで、一通り勉強した後何やろうかなと思い、gRPCに手を出してしまいました。。
と言うのも、WEB+DB PRESSのvol.114でkyashの特集をやっており、Goのアーキテクチャなどが紹介され、**マイクロサービス** 化を実践してみたくて、gRPCに興味が湧きました！

そこで、[よく分かるgRPC](https://booth.pm/ja/items/1557285)の良書があったのでそちらをまとめて行きたいと思います。

## gRPCとは？

言わずもがなGoogleが開発しているRPC用のフレームワーク
RPCとは異なる場所にあるプログラムを呼び出すための仕組みを指します。
イメージとしては外部APIとHTTP通信でJSONを用いてやり取りする様な物です。

- HTTP/2の仕組みを用いた高速な通信
- Protocol Buffersを使ったRPCの定義とコード生成(レビューも出来ちゃう！)

もうここまで言うとマイクロサービスにドチャクソ向いてるのは分かりますよね！？

## 動かしてみる

色んな記事にある様に、チュートリアルしてもらうのが一番早く、確実です。

https://grpc.io/docs/quickstart/go/

ここではコードの書き方を何となく理解できればグッドです！

## gRPCの仕組み

### RPC
gRPCの単一の呼び出しはRPCと言います。
RPCには種類が4つあります。

- Unary RPC
- Server streaming RPC
- Client streaming RPC
- Bidirectional streaming RPC

これはよくあるgRPCの記事で言うそれぞれ上から

- 1リクエスト1レスポンス
- 1リクエストNレスポンス
- Nリクエスト1レスポンス
- NリクエストNレスポンス

と言うやつの正式名称ですね！

チャットとかの実装だとBidirectional streaming RPCを使います。

### Channel (goのchannelとは別)
gRPCの裏側を支える代表的な要素がこのChannel(goではClientConn)
gRPCの通信を行うための経路の様な物

Channelはいくつかの状態を持ちます。
最後に切断するまで状態が切り替わっていく様になっています。

- CONNECTING
- READY
- TRANSIENT_FAILURE
- IDLE
- SHUTDOWN

Channel作成直後はCONNECTINGから始まり、使い終わるとSHUTDOWNになります。

### gRPCとHTTP/2

gRPCはHTTP/2の元、通信を行っています。
HTTP/2に関しては[そろそろ知っておきたいHTTP/2の話](https://qiita.com/mogamin3/items/7698ee3336c70a482843)で概要が掴めるかと思います。

個人的に一番「うｵ！！」っと思ったのは
今まで1リクエスト1レスポンだったものが **Streamが導入され、複数の通信を行える様になった** と言う点です！(すごい。。)

- Connection
- Stream
- Frame

このワードを押さえてください。

ひとつのRPCに大してひとつのHTTP/2 Streamが対応しています。
そしてそれら(Connection, Stream)を管理しているのがgRPCのChannel(goではClientConn)です。
ネットワークエンジニア視点のAWS  Direct Connect

 AWSの勉強をしているとネットワークエンジニア的に良く分からない点が出てくるので、
勝手にネットワークエンジニアの視点で解釈した内容を書きます。
中の方や詳しい方から見たら、それは違うだろ！というのがあるとは思いますが、
その際はご容赦を＆ご指摘いただければと。

###まずはDirect Connectの基本構成に関して。
<img width="475" alt="Screen Shot 2020-01-01 at 18.19.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200070/9592dd2c-b14e-9114-3990-d6c1c6ac5f0a.png">
このように考えるとスッキリしました。
このRouter (VPC)は新しいInterfaceを持つためには、Network Module
(イメージ的にはSwitching Module？)を空きslotに入れて、Interface Card(port数は1)を
Network Moduleに挿入する。
このInterface Card上のinterfaceはTrunk設定＆SVIは必須で, SVIは一つしか設定出来ない。
そのSVIをsourceとしてBGP peeringを行う。

なので実際のAWSでの設定も、まずはVGW作ってVPCにアタッチして、Virtual Interface作って
VGWにアタッチして、と(上記のRouterに直接interface Cardは刺さらない、みたいな)。

###次に、Direct Connect Gateway
<img width="597" alt="Screen Shot 2020-01-01 at 18.22.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200070/51a911a5-e53b-f9b5-c3a0-63505a2d44dc.png">
Direct Connect Gatewayは複数ルータで共有可能なPoint-to-multipointの外付け拡張ファブリック。
内部的にはpoint-to-pointで各ルータ(VPC)に搭載したNetwork Module(VGW)と外付けinterface card
(Private VIF)を接続。Private VIFがHubで各ルータがSpokeとして機能。Spoke間の通信は出来ない。
(ファブリックなので、Private VIFとVGW間のaddress の設定等は無し)

特にDirect Connect Gatewayの矢印部分に対するip addressの設定箇所が無いので、
ここはinterfaceと考えるよりは、**内部的なBus**と捉えるべきかなあと思いました。
昔のCat6kのスイッチングファブリックみたいなイメージ。
App Service Tips - App Service on Linuxの作成が失敗する

#概要
開発中にAzure ポータルから既存のリソースグループに対して
App Service on Linuxを作成しようとしたら、なぜか失敗。
その時の調査結果。

#エラー内容
デプロイが失敗し、以下のようなエラーメッセージが通知されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/ca325db2-ccd1-6a12-d002-7047f0e22ecc.png)

エラーの詳細を確認すると、以下のようなログが残っていました。
Requested feature is not available in resource group XXXX


#原因
2020年1月1日現在では、リソースグループ内にWindowsのApp Serviceと
LinuxのApp Serviceを同居させることはできないんだそうです。
[https://docs.microsoft.com/ja-jp/azure/app-service/containers/app-service-linux-intro#limitations](https://docs.microsoft.com/ja-jp/azure/app-service/containers/app-service-linux-intro#limitations)

#雑記
地味にハマる制限事項でした・・・。

今回、ASP .Net Coreで開発していて、App Serviceにデプロイしてたんですが、
コスト的に安いApp Service on Linuxに置き換えようと考えたんですよね。
ということで、試しに作ろうとしたら、できなかったというわけです。

ちなみに、Visual Studio 2019上からリソースを作成することができるんですが、
VS2019はここの制限をフォローしてくれているようです。
⇒App Service on Linuxを作成しようとした際のリソースグループ選択リストから、
　すでにApp Serviceが存在するリソースグループが除外されてました。
Express (Node.js) の Graceful shutdown


基本的な実装の仕方と、実装した場合 / しなかった場合、で実際にどういう動作をするか〜、について書きます。

> Linux, Node.js 12.13.0, での話だけをします。

## Graceful shutdown ?

[Express] \(Node.js\) に限りませんが、Web サーバーを停止する際、クライアントから接続中のリクエスト (リクエスト受付してまだレスポンスしていない接続) はどうなるでしょうか？

Graceful shutdown とは一般的に以下の停止を指します。

* 停止指示後に、新しい接続を受付しない
* 残った処理中の接続が完了するのを待ってから、プロセスを安全に停止する

## SIGNALs

そもそも Web サーバープロセスはどうやって停止するかというと、 [SIGNAL] を用いて停止します。

具体的には下表の通り、コマンド等によって [SIGNAL] を送信できます。

| SIGNAL  | kill command | Linux Terminal | Kubernetes | 実装依存 | 説明 |
|:--------|:-------------|:---------------|:-----------|:-------|:----|
| SIGHUP  | kill -SIGHUP {pid} | -- | -- | Yes | プロセスが端末から切断された際のシグナル |
| SIGINT  | kill -SIGINT {pid} | CTRL + C | -- | Yes | 割り込み |
| SIGKILL | kill -SIGKILL {pid} | -- | SIGTERM 送信から30秒後に送信 | **NO** | プロセスの実装に依存しないOSからの強制終了 |
| SIGTERM | kill {pid} | -- | 最初に送信 | Yes | プロセスの終了 |

> 最近では、プロセスを [Docker] コンテナ化して、 [Kubernetes] 等のプラットフォーム上で動かす事が多いと思います。

> 例えば [Kubernetes] では、プロセス ([Docker] コンテナ) を終了する際は、まず ``SIGTERM`` が送信され、30秒待ってもプロセスが終了しない場合、最終的に ``SIGKILL`` が送信されます。

>> [Kubernetes - Pods - Termination of Pods]

## 実装例 

URL ``/sleep`` と、 SIGNAL ``SIGTERM`` での Graceful shutdown を [Express] で実装しました。

```javascript:index.js
const express = require('express');

const SLEEP_MSEC = 30 * 1000;
const app = express();

app.get('/sleep', (req, res) => {
  setTimeout(() => res.send('OK'), SLEEP_MSEC);
});

const server = app.listen(3000, () => console.log('Example app listening on port 3000!'));

process.on('SIGTERM', () => {
  server.close(() => {
    console.log('Process terminated.')
  })
});
```

実行します。

```shell
$ node index.js

Example app listening on port 3000!
```

ブラウザで以下の URL にアクセスすると、30秒待たされた後 ``OK`` と表示されます。

* http://localhost:3000/sleep

## [未実装で] 実際に停止してみる

まずは **未実装の状態で** どう動作するか検証します。

Express サーバーを起動した後、ブラウザで http://localhost:3000/sleep にアクセスします。
まだリクエストの処理中に [SIGNAL] を送信します。

### (1) SIGHUP

シグナルを送信でプロセスが即座に停止。

```shell
kill -SIGHUP {pid}
```

```
Hangup: 1
```

### (2) SIGINT

シグナルを送信でプロセスが即座に停止。

```shell
kill -SIGINT {pid}
```

```
(terminal 上の出力はなし)
```

### (3) SIGKILL

シグナルを送信でプロセスが即座に停止。

```shell
kill -SIGKILL {pid}
```

```
Killed: 9
```

### (4) SIGTERM

シグナルを送信でプロセスが即座に停止。

```shell
kill {pid}
```

```
Terminated: 15
```

## [SIGTERM 実装で] 実際に停止してみる

> 実装していない ``SIGTERM`` 以外のシグナルは省略。

### (5) SIGTERM

ブラウザで http://localhost:3000/sleep にアクセスする。

> 応答がすぐには帰ってこず、ローディング状態になります。

シグナルを送信します。

```shell
kill {pid}
```

プロセスは実行されたまま、無反応。

```
(terminal 上の出力はなし)
```

ブラウザから新しいタブを開いて http://localhost:3000/sleep に追加でアクセスする。

> TCP 接続が拒否され、ブラウザ上に「正常に接続できませんでした」と表示される。

1度目のブラウザからのリクエストが 30 秒後に正常に応答が返り、プロセスが終了する。

```
Process terminated.
```


[Express]:https://expressjs.com/ja/
[SIGNAL]:https://linuxjm.osdn.jp/html/LDP_man-pages/man7/signal.7.html
[Kubernetes]:https://kubernetes.io/ja/
[Docker]:https://www.docker.com/
[Kubernetes - Pods - Termination of Pods]:https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods
【Python】Tkinterによる複数ウィンドウの作成

# はじめに
こんにちは。

この記事ではTkinterを用いた複数のウィンドウを作るためのソースが分かる記事となっています。
よろしくお願いします。

# 環境
- Windows 10 home
- Python 3.7.1

# ソースコード

こちらが完成したソースコードになります。
ぜひ実行してみてください。

```main.py
import tkinter as tk

class Application(tk.Frame):
  def __init__(self,master):
    super().__init__(master)
    self.pack()
    master.geometry("300x300")
    master.title("ベースウィンドウ")

    self.window = []
    self.user = []

    self.button = tk.Button(master,text="ウィンドウ作成",command=self.buttonClick,width=10)
    self.button.place(x=110, y=150)
    self.button.config(fg="black", bg="skyblue")

  def buttonClick(self):
    self.window.append(tk.Toplevel())
    self.user.append(User(self.window[len(self.window)-1],len(self.window)))

class User(tk.Frame):
  def __init__(self,master,num):
    super().__init__(master)
    self.pack()
    self.num = num
    master.geometry("300x300")
    master.title(str(self.num)+"つ目に作成されたウィンドウ")

    self.button = tk.Button(master,text="コンソール上での確認",command=self.buttonClick,width=20)
    self.button.place(x=70, y=150)
    self.button.config(fg="black", bg="pink")

  def buttonClick(self):
    print("こちらは"+str(self.num)+"つ目に作成されたウィンドウです。")

def main():
  win = tk.Tk()
  app = Application(win)
  app.mainloop()

if __name__ == '__main__':
  main()
```

# 実際の動作

このプログラムを実行してみると、まずベースウィンドウが表示されます。
次に、ベースウィンドウにあるボタンをクリックすると、新たなウィンドウが作成され、表示されます。
作られたウィンドウにあるボタンをクリックするとコンソール上に、このウィンドウが何個目に作成されたのかを表示してくれます。

ベースウィンドウにあるボタンをクリックすれば、いくつでも新たなウィンドウを作成することができますので、ぜひ試してみてください。

ここまで読んでいただき、ありがとうございました。
[iOS]Viewの一辺（片側）に点線を引く

参考までに

```swift

///利用側
func _() {
    hogeView.addOneSideDashBorder(position: .bottom, color: .red, lineDashPattern: [5, 5])
}

extension UIView {
    /// 一辺に点線を引く
    @discardableResult
    func addOneSideDashBorder(position: BorderPosition, color: UIColor, lineDashPattern: [NSNumber]?) -> CALayer {
        layoutIfNeeded()

        let shapeLayer = CAShapeLayer()
        shapeLayer.lineDashPattern = lineDashPattern
        shapeLayer.strokeColor = color.cgColor
        shapeLayer.frame = bounds

        let line = UIBezierPath()
        switch position {
        case .top:
            line.move(to: bounds.leftTop)
            line.addLine(to: bounds.rightTop)
        case .left:
            line.move(to: bounds.leftTop)
            line.addLine(to: bounds.leftBottom)
        case .right:
            line.move(to: bounds.rightTop)
            line.addLine(to: bounds.rightBottom)
        case .bottom:
            line.move(to: bounds.leftBottom)
            line.addLine(to: bounds.rightBottom)
        }

        shapeLayer.path = line.cgPath
        layer.addSublayer(shapeLayer)

        return shapeLayer
    }
}

/// 上下左右
enum BorderPosition {
    case top
    case left
    case right
    case bottom
}

/// 
extension CGRect {
    var leftTop: CGPoint {
        return CGPoint(x: 0, y: 0)
    }
    var rightTop: CGPoint {
        return CGPoint(x: width-1, y: 0)
    }
    var leftBottom: CGPoint {
        return CGPoint(x: 0, y: height-1)
    }
    var rightBottom: CGPoint {
        return CGPoint(x: width-1, y: height-1)
    }
}

```


結果

<img width="375" alt="Simulator Screen Shot - iPhone X - 2020-01-01 at 18.02.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20784/44ad4cc9-5230-a88b-b5c6-395698f6078b.png">

考えたら実線もこっちでいいのではないでしょうか？
borderを使う方法のほうが一般的ですが、ソッチのほうがいい理由はあるのか（ちょっとわかりません）

```swift

extension UIView {
    /// 一辺に実践を引く
    @discardableResult
    func addOneSideBorder(position: BorderPosition, color: UIColor) -> CALayer {
        layoutIfNeeded()

        let shapeLayer = CAShapeLayer()
        shapeLayer.strokeColor = color.cgColor
        shapeLayer.lineWidth = 1
        shapeLayer.frame = bounds

        let line = UIBezierPath()
        switch position {
        case .top:
            line.move(to: bounds.leftTop)
            line.addLine(to: bounds.rightTop)
        case .left:
            line.move(to: bounds.leftTop)
            line.addLine(to: bounds.leftBottom)
        case .right:
            line.move(to: bounds.rightTop)
            line.addLine(to: bounds.rightBottom)
        case .bottom:
            line.move(to: bounds.leftBottom)
            line.addLine(to: bounds.rightBottom)
        }

        shapeLayer.path = line.cgPath
        layer.addSublayer(shapeLayer)

        return shapeLayer
    }
}
```

追記：欠点見つけました。borderと違い、Viewのframeに連動してくれないので付け替えが面倒ですね。
DualSPHysicsのインストールとDambreak

#粒子法とは？DualSPHysicsとは？

本記事の目標は，OSSの粒子法ソフトであるDualSPHysicsを導入し，
テストケース"01_Dambreak"を__とりあえず__実行できることです．

[粒子法](https://ja.wikipedia.org/wiki/%E7%B2%92%E5%AD%90%E6%B3%95)とは計算対象物を粒子の集まりとして表現し，連続体に関する微分方程式を数値的に解くための離散化手法の一つです．
計算格子を持ちないことから，大きな変形を取り扱うことができ，相変化をモデリングすることができることに強みがあります．
粒子法は微分演算子の定義およびタイムステップの取り扱いの違いから
MPS（Moving Prticle Simulation）法およびSPH（Smoothed Particle Hydrodynamics）法に分類されます．
DualSPHysicsはSPH法を用いた，オープンソースの粒子法ソフトウェアです．
本記事ではオープンソースによるシミュレーションの初学者が，DualSPHysicsのテストケースを実行する過程をメモとして残します．
#DualSPHysicsのインストール
DualSPHysicsのインストール方法は2種類存在する．DualSPHysicsの[公式Webサイト](https://dual.sphysics.org/)からソースコードをダウンロードする方法と，[GitHub](https://github.com/DualSPHysics/DualSPHysics)を経由する方法である．[1]

公式サイトからのインストールでは全てのテストケースを含んだ完全版が提供される．しかし提供されるバージョンは最新版ではなく，リリース後一定期間が経過し，安定性が確認されたバージョンである．[1]

GitHub経由のインストールでは最新版を含めた，
任意の開発段階のソースコードをインストールすることができる．
しかし，全てのテストケースが含まれているわけではなく，
01_Dambreakのみ使用することができる．[2]

ここでは__テストケースをとにかく実行して可視化すること__が目的なので，安定性が高く，多くのテストケースを含む，[公式サイトのコード](https://dual.sphysics.org/)をダウンロードし，Linux（Ubuntu16.04）上での実行していきます．

公式サイトでのダウンロード方法は以下の通りである．
メニュー上段左から４つ目の[Download](https://dual.sphysics.org/index.php/downloads/)をクリックする．
入力フォームに最低限の個人情報を入力し，送信する．
するとダウンロードリンクが表示される，仕組みである．[2]

送信する個人情報は以下の通り  
- Name
- Organization
- Commercial use or research
- Area of expertise
- Country
- E-mail

これらを入力し（メールアドレスさえ通れば後は適当でよい）
PreviousVersionの欄にある「DualSPHysics_v4.2.zip」にチェックを入れる．
さらにsubmitをクリックする．

するとダウンロードリンクが張られたページが表示される．
クリックしてダウンロードし，zipファイルを展開する．

DualSPHysicsディレクトリ内には  __bin, doc, example, src_*__などのディレクトリがある．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197157/f038e19f-590d-f69d-674c-9a8188399915.png)

binディレクトリにはコンパイルした後の実行ファイルが含まれている．
後にも述べるが，環境により，binディレクトリ内のコマンドへのアクセスが制限されている場合がある．
この場合は全コマンドのパーミッションを変更しておく．
docディレクトリにはUserGuideやXMLファイルのフォーマットファイルが含まれている．
srcディレクトリにはコンパイル前のソースコードが含まれている．

#Dambreakの実行

この記事ではテストケース「01_Dambreak」の実行を行う．
まずディレクトリ　DualSPHysics_v4.2/example/main/01_Dambreak
に移動する．

ダムブレイクは粒子法の最も代表的な計算例のひとつである．
テストケースには2次元と3次元に対してそれぞれCPU並列，GPU並列の計算例（合計4種類）が含まれているが，本記事ではとりあえずプログラムを実行して結果を可視化することが目的なので二次元CPU並列プログラムの実行を行う．

Dambreakの実行を行うためには
シェルスクリプト
xCaseDambreakVal2D_linux64_CPU.sh
を実行する．

```shell
sh xCaseDambreakVal2D_linux64_CPU.sh
```

シェルスクリプトには前処理，計算，後処理のためのコマンドが含まれている．（詳細は後の記事で解説）
実行して前処理が成功し，計算が始まると以下の画像のような画面になる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197157/a7cab805-3a7b-d1af-107d-c9597e24e817.png)

環境にもよるが，シェルスクリプトで参照しているコマンドへのアクセスが禁止されている場合があるので（僕の場合は禁止されていた）その場合は
DualSPHysics/bin/linux
に存在する全コマンドのパーミッションを変更する必要がある．

[次の記事](https://qiita.com/oyroooo/items/70b9a614b279b485b3ec)ではParaviewを用いた可視化を行います．

#参考文献
[[1] O. Garcia: Developing on DualSPHysics, (2018)](https://github.com/DualSPHysics/DualSPHysics/blob/temperature/doc/Developing%20on%20DualSPHysics.pdf)
[[2] dual.sphysics.org](https://dual.sphysics.org/)
レジストリをイジってcaps lockをEscにaliasする

結構使いやすい場所にあるにも関わらず、あまり使わない**不遇**のキー`caps lock`を、`vimmer`なら小指が折れそうになるほど使う`ESC`にしちまおうぜ**ゲヘヘ**

# やり方

1. `win + r`
2. 「ファイルを指定して実行」から`regedit`を起動(要: 管理者権限)
3. `コンピューター\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout`を開く
4. 右クリック - **新規** - **バイナリ値**を作成する
5. 名前を`Scancode Map`に変更

## バイナリ値の修正

![reg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246065/94a44124-441b-811e-d1da-e4c8f090ee95.png)

```
00 00 00 00 00 00 00 00
02 00 00 00 01 00 3A 00
00 00 00 00
```

一応レジストリを弄るので、手順通り出来ているか確認しつつ作業して下さい。

ちゃんと出来たことを**指差し確認**したら、PCを**再起動**しましょう。

# 参考, 引用

- [レジストリでキー配列変更 -Qiita](https://qiita.com/matsu-tk/items/9059ff186fdfc716bf65)
- [レジストリを修正してCAPSLOCKの割り当て変更](http://yanor.net/wiki/?Windows%2FTIPS%2F%E3%83%AC%E3%82%B8%E3%82%B9%E3%83%88%E3%83%AA%E3%82%92%E4%BF%AE%E6%AD%A3%E3%81%97%E3%81%A6CAPSLOCK%E3%81%AE%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E5%A4%89%E6%9B%B4)
javafxでRPG

この記事は書きかけです。

#環境
- Java8を使います。

#まずはHello,World!

```Main.java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

import javafx.scene.Group;
import javafx.scene.text.Text;
import javafx.geometry.Pos;

public class Main extends Application{
    public static void main(String[] args){
        launch(args);
    }
    
    public void start(Stage stage){
        Group p = new Group();
        stage.setScene(new Scene(p,480,352));
        stage.show();

        Text t = new Text("Hello,World!");
        p.getChildren().add(t);
    }
}
Python3で配列をクイックソートする

<h2>はじめに</h2>
<p>皆さん2020年あけましておめでとうございます。ryuichi69と申します。<br>本日もアルゴリズムの練習のアウトプット、説明の練習がてらこの文章を書きました。正直分かりやすく書くのが大変で、説明の分かりにくい部分、要件漏れ等がありましたらご連絡下さい。</p>

<h2>クイックソート</h2>
<h4>概要</h4>
<p>まずソートとは、配列の要素を昇順または降順に並び替える事を言います。</p>
<p>ソートの方法は何種類もありますが、そのうちクイックソートとは、<b>配列の基準値を起点として、それより大きいものの配列、小さいものの配列に小分けにしていって行ってソートしていく手法</b>です。</p>
<h4>クイックソートの例</h4>
<p>例えば配列a=[5,6,3,1,8]があり、これを昇順にクイックソートする事を考えます。さらに配列内の中央値を基準値とします。</p>
<p>ここで配列aの要素の中央値は3ですね。この3を境目に3より小さい要素を下の青、3より大きい要素を下の黄色のように、半分に2分割していきます。さらに下の図の2回目の分割のように、再帰的に配列を半分に分割していき、配列の要素数が1つになった時点で再帰を打ち切ります。最後に１つの配列に統合して完成です。</p>

![sort.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39145/e6966dcd-7ace-6d76-a4e2-579ed97b73ae.png)


<p>ここで実装の手順をまとめると、</p>
<h4>実装の手順</h4>
<ol><li>配列a[i]の要素eの中央値m(基準値)を探します。</li><li>分割後の配列の要素数が1個になったら、再帰を打ち切る処理を書く(再帰の停止条件)。</li><li>配列の各要素elementごとに。a[i] < mの場合はelementを配列left、a[i] > mの場合はelementを配列rightに値を格納します。</li><li>配列left、配列rightに対し上記1～2を再帰的に実行します。</li></ol>

<h2>例題</h2>
<p>nを自然数、iを0≦i≦(n-1)を満たす整数とする。このときクイックソートにより、n個の要素を持つ配列a[i]を昇順にソートせよ。</p>

<h5>制約</h5>
<ol><li>1≦n≦10</li><li>1≦a[i]≦10</li></ol>

<h5>入力</h5>
<p>a = [7,3,10,5,9,1,6,4,8,2]<br>
</p>

<h5>出力</h5><P>[1,2,3,4,5,6,7,8,9,10]</p>

<h2>プログラム</h2>
<p>ソースコードは、@suecharoさんの「<a href="https://qiita.com/suecharo/items/30f5d817da4c948c3be6" target="_blank">ソートアルゴリズムと Python での実装 - Qiita</a>」のクイックソートのものベースとしています。配列を2つに分けてソートする点が分からなかったので、カンニングさせて頂きました。</p>

```Python:quickSort.py
import os
import statistics

def quickSort(arr):

    # 配列のメジアンより小さい要素を集めた配列
    left = []

    # 配列のメジアンより大きい要素を集めた配列
    right = []

    # 再帰の停止条件
    # 再帰的に配列を分割した後の、要素数が1以下になったら停止する
    if len(arr) <= 1:
        return arr

    # 配列の中央値(メジアン)を取得する
    median = int(statistics.median(arr))

    # 配列内に含まれる中央値の個数を数えるための変数
    medianFlg = 0

    for element in arr:
        # 配列の要素(element)が中央値より小さいので、
        # 配列leftに値を格納する
        if element < median:
            left.append(element)
        # 配列の要素(element)が中央値より大きいので、
        # 配列rightに値を格納する
        elif element > median:
            right.append(element)
        else:
        # elementが配列の中央値の場合は、
        # 返り値に加える中央値の個数分だけ、フラグに+1し続ける
            medianFlg += 1

    # 配列がどのように分割されているかを確かめたい場合は、
    # このタイミングでprintで確認すると良い
    # print(left)
    # print(right)

    # 配列left、配列right毎に再帰を行い
    # 配列を小さな配列に区切る
    left = quickSort(left)
    right = quickSort(right)

    # 配列left、中央値の[median]、配列rightを結合したものを返す
    return left + [median] * medianFlg + right

# テスト用
if __name__ == "__main__":

    print(quickSort([7,3,10,5,9,1,6,4,8,2]))

```
:terminal on vim8で生きてる人のための:bw設定

## 対象読者

* Terminal.app だの iTerm2 なんて捨てた
* vim 起動して `:terminal` で生きてる

## 背景

vim 8 の:terminalで生きてる。
iTerm.appのaliasに`gvim` とか設定するレベル。

最初の頃は、`:terminal` の中で `exit` とすると、
terminal bufferだけがcloseされて、他のバッファに切り替わったんだけど、
ちょっと前から普通のバッファを`:q`したときと同じ挙動に変わった。
要は「terminalが最後のwindowだと、vimごと終了する」。
（参考： `:h terminal-close`）

基本vimにいて、たまにterminalを使うみたいな使い方だとこれが非常にだるい。

## 方針

ExitPreとかでフックして終了処理止めちまえと思ったんだけど、
そんな方法が見つからなかったのと、ExitPreは終了直前の処理なので、echomとかしてもログ見れなくてだるい。

ので、

* terminal は基本++nocloseで使う
* terminal の中のシェルの方で特殊な終了処理をする

という方向で攻めた。

## 結論

```vimrc.vim
nnoremap <silent> tt :<C-u>terminal++curwin ++noclose <CR>
nnoremap <silent> tx :<C-u>terminal++noclose         <CR>
nnoremap <silent> tv :<C-u>vertical terminal++noclose<CR>

" ++nocloseで開くので、exitしたらそのままbuffer wipeoutしたい。
" zshrcの方で function :bw() としてこいつを呼び出してexitするコマンド :bw を定義済
function! Tapi_WipeoutTerminalBuffer(bufnum, arglist)
  autocmd! SafeState <buffer> ++once bwipeout
endfunction
```

```zshrc.zsh
  # :bw で exit -> noclose指定のterminalウインドウを閉じる
  function :bw() {
    echo -ne "\033]51;[\"call\", \"Tapi_WipeoutTerminalBuffer\", []]\07"
    exit
  }
```

`terminal-api` が便利。
流石に `exit` をoverrideするの、トラブったときにやな感じだなと思ったので、
exitっぽいコマンドをzsh側で定義してる。
M5StickC を HomeKit に対応する

iPhoneのホームアプリから、M5SticCのLEDをON／OFF制御できます。
また、Siriによる音声コントロールも可能です。

![IMG_9654.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452335/e1936d50-0fd3-555d-014e-650a071ebb60.jpeg)

# 1. 事前準備
ESP-IDF開発ツールをインストール https://qiita.com/SamAkada/items/67551f3e2ff6ac602215

# 2. ダウンロード
```
$ git clone https://github.com/SamAkada/esp32-homekit.git
$ cd esp32-homekit
$ git submodule update --init --recursive
```
# 3. WiFi設定
```
#define EXAMPLE_ESP_WIFI_SSID "mywifi"
#define EXAMPLE_ESP_WIFI_SSID "mypassword"  
```
- ソースコードを開く examples/M5StickC-led/main/main.c
- EXAMPLE_ESP_WIFI_SSID と EXAMPLE_ESP_WIFI_PASS を変更する

# 4. ビルド
```
$ cd examples/M5StickC-led
$ make
$ make flash
```

# 5. Setup Code
## 111-22-333
2020年の抱負

あけましておめでとうございます。

エンジニア的観点で2020年をどういった年にしたいか書いていこうと思います。

# 抱負
年末年始、皆さんどうお過ごしでしょうか。
仕事をしている方もいれば、自分のスキルを磨いてる方、Amazon VideoやNetflixでだらだらビデオを見てるのでしょうか。
そんな自分は本業が忙しく、ひたすらデレステとミリシタでシャンシャンやってます。

シャンシャンやってるのが人生においては無意味かもしれませんが、楽しく満たされた気持ちにはしてくれます。嗜好品と一緒ですね。

前置きはほどほどにして、シャンシャンとは別に私も自分のスキルを磨くことを考えていました。
正確にはどんなスキルを磨くべきなのかを考えていた、ですね。
特に、今年34歳になる私の頭の中の大半は **【プログラマ35歳限界説】** が占めています。
40歳でもプログラマしてるよ、とかいろいろ意見があるとは思いますが。

私たちエンジニアは、半年前には最新だった技術が古くなり、1年後には廃れて使われなくなったり、この技術が今後くる！と言われるも結局来なかったり、全部追うのが困難なほどどんどん新しい技術が生み出されてたり。大げさかもしれませんが、ちょっと先すら見通せない荒れ狂う海を航海している様な激動の世界で生きています。
(見通せてる人、ビジョナリーな航海士がいたら教えてください。ブログとか読みあさりたい！)

ではそんな世界で、どう目標を立てていこうか考えてみました。

- 短期的な目標: 具体的な言語だったり、サービス、ツールの使い方を覚える。
    - まずは、アサインされるであろうプロジェクトに必要なスキルを磨いていこうと思います。
- 中長期的な目標: 上で示したものが動く仕組みであったり、より抽象的な概念を理解する。
    - 特定の言語やサービスに依らない概念やアルゴリズム、フレームワークをアドバイス、または実装出来る様にまずはベースとなる知識を蓄えていこうと思います。

今年どんな技術が流行るか分かりませんが、 **流行り廃りに流されない地に足のついた** エンジニアを目指そうと思います。
使いやすいサイトのタネ

使いやすいサイトを作るためにできそうなことをメモ。

##もろもろ
・ボタンを少なくする

・フレンドリーフォワーディング

・404画面をいい感じにする

・ページネーションの「前へ」「次へ」ボタンとページ数の数字はどちらか片方だけを使う方が好き。

・外部リンクは、アイコンで別タブで表示することを明示した上で`target="_blank"`をつけるとやさしくて使いやすい

・ヘッダーのロゴをリンクにする

・背景クリックでポップアップを閉じる

・複数のサービスのアカウントでログインできる仕様の場合、前回何でログインしたかを表記する

・設定変更画面では「更新」ボタンがあったほうが安心。

・処理に時間のかかる部分にはローディングアニメーション等を入れる

・クリックできる要素は、それがわかるようにする。押しやすい大きさを確保する

・ページャーは「1 2 3 4 ... 6」とかにして、「...」の部分も1つのボタンにすると良い感じ

・アイコンがリンクになっている場合文字を添える or　ツールチップを使う

・ページ内リンクは遷移後にハイライトする
https://twitter.com/takamosoo/status/1293671419482525696?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1293671419482525696%7Ctwgr%5E&ref_url=https%3A%2F%2Fnote.com%2Ftakamoso%2Fn%2Fn9f9682e885e1

##フォーム
・フォームの入力値には、`pattern`属性とjsの正規表現で入力制限をつけると親切
参考：[pattern、type属性のおさらい](https://qiita.com/ka215/items/795a179041c705bef03b)

・郵便番号から住所を自動で入力
[ajaxzip3](https://y-com.info/contents/?p=6656)


・入力された電話番号や郵便番号にハイフンが含まれていた場合、エラーを出すのではなく裏側でハイフンを取って保存する

・メールアドレスに大文字が含まれていた場合にも、裏側で小文字に変換する

・住所登録フォームを1つにまとめる
→「郵便番号上3桁、下4桁、都道府県、市区町村、番地」みたいに別れていると使いにくい

・入力した時に褒めてくれる
→「良いメールアドレスですね」など

・入力が終わっていない時に「不正な形式です」的なエラーが出るとムカつく

##好きなアニメーション
アニメーションは基本好きじゃないけど、以下のアニメーションはありだと思う。

・ヘッダーの幅がスクロールで狭くなる
https://startbootstrap.com/previews/freelancer/

・スムーズスクロール
https://codepen.io/manabox/pen/NVdePj

・無限スクロール、はてなブックマークのやつが良い感じ
https://b.hatena.ne.jp/nyshk97/bookmark
10件ごとにページネーションが出てくるけど、無限スクロールにもなっている。
単純な無限スクロールだと、どこで一区切りつけるかの判断が難しくなってしまう。

・記事を読み進めるとサイドバーが暗くなる
https://ja.nuxtjs.org/guide/
【AWS完全に理解したへの道】IAM 基本編

[【AWS完全に理解したへの道】 S3 基本編](https://qiita.com/y-u/items/9517ab2570a4e823fbb8)
に続く、IAM 基本編(項目の然るべき順序的なものは後で整理するかも)

### 特徴
* AWS内のユーザ管理やAWSリソースに対するアクセス制御を行うためのもの。
* 仮にアクセス許可と拒否のIAMポリシーが相反する場合、拒否のIAMポリシーが優先される。

##### AWSサービスを操作する方法と認証情報
|操作方法|認証情報|
|---|---|
|Webブラウザ|ユーザ名/パスワード|
|AWS CLI(コマンド)|アクセスキー/シークレットアクセスキー|
|AWS SDK|アクセスキー/シークレットアクセスキー|

#### アクセスキーとシークレットアクセスキー
各IAMユーザはアクセスキーとシークレットアクセスキーのペアを作成・保持することができ、そのペアをAWS CLIやAWS SDKの認証情報として利用することができるが、認証情報を更新漏れや流出の危険性から非推奨となっている。

#### アクセスキーとシークレットアクセスキーを使用せずに推奨されること
IAMロールを利用することが推奨されている。
IAMロールは各種リソースに対するアクセス可否(IAMポリシー)を設定できる。
IAMロールはEC2インスタンスなどに割り当て可能で割り当てられたEC2インスタンス上のプログラムはIAMロールに許可されているAWSリソースにアクセス可能。

### IDフェデレーション
AWSのSTS(Security Token Service)を使用して一時的に認証情報をユーザに付与する。そして、そのSTSとAWSのIDプロバイダーを利用して、AWS外の認証基盤で認証を通すことでIAMユーザに登録することなしに、一時的なリソースアクセスの権限を得ることができる。

### Link
[ID プロバイダーとフェデレーション](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers.html)
Unityでゲームつくりてえ。：自機狙い

自機…というか特定の目標を狙って移動させてえ。

# 自機の方を向かせてまっすぐ移動、という手もある。

こんな感じのを作り、targetに自機を入れる。

```C#
public void lookAt(GameObject target,float speed) {
    transform.LookAt(target.transform);
    GetComponent<Rigidbody2D>().velocity = transform.forward.normalized * speed;
}
```
transformには向きというものがあって？
LookAtを使えば特定のオブジェクトを向かせることができて？
forwardで向きに対しまっすぐに移動させることができる、らしい。

ただこれ、やってみるとわかるが、向きを変えると**オブジェクトの見た目の向きも変わる。**
ドットバイドット的なゲームを目指す場合だと、これはきびしい（逆にそこまで気にしないなら、便利なものは使おう）。

**さっそく追記（2020/01/01）**
http://karaagedigital.hatenablog.jp/entry/2016/09/11/192600
平面が向きを変えてしまうようで、そのままでは2Dではつかえないとのこと。
グラフィックを伴わないオブジェクトなら使いようもあるかもですが、うーむ。


# 自機の角度を得て、その方向に動かす。

targetに自機を入れると、自分から自機…えーと、「このスクリプトを動作させてる本人」から「目標（自機）」への角度が得られる。

```C#
public float target(GameObject target) {
    float x = target.transform.position.x - this.transform.position.x;
    float y = target.transform.position.y - this.transform.position.y;
    float rad = Mathf.Atan2(y,x);
    return rad * Mathf.Rad2Deg;
}
```

すーがくわからんので、なぜ、という説明はできません。すまん。

こちらは角度を食わせるとその方向に移動するスクリプトになります。
zにさっき得た角度を、objには自分のリジッドボディ2D（Rigidbody2D）を食わせる。

```C#
public void moveZ(float z,float speed,Rigidbody2D obj) {
    Vector2 move;
    move.x = Mathf.Cos(Mathf.Deg2Rad * z);
    move.y = Mathf.Sin(Mathf.Deg2Rad * z);
    obj.velocity = move * speed;
}
```
毎回角度取得と移動を行えば、誘導弾（自機が逃げても追いかける）になる。
初回のみ角度取得し、その角度で移動すると、自機狙い弾（自機にまっすぐ飛ぶ）になる。
git configコマンドを実行しようとしたらxcrun: errorになった

## エラー内容
githubのUserNameを変更したので、ローカルのUsernameも変更しようとしたら下記のエラーが出た。

```
$ git config --global user.name 'NewUserName'
xcrun: error: active developer path ("/Users/User/Downloads/Xcode.app/Contents/Developer") does not exist
Use `sudo xcode-select --switch path/to/Xcode.app` to specify the Xcode that you wish to use for command line developer tools, or use `xcode-select --install` to install the standalone command line developer tools.
See `man xcode-select` for more details.
```

エラー文をそのままコピペして調べると、`xcode-select --install`しなさいと出たので実行。

```
$ xcode-select --install
xcode-select: error: command line tools are already installed, use "Software Update" to install updates
```
またエラーに。
再びググると、XCodeのCommand Line Toolsのパスを修正する必要があることがわかった。

## パス修正手順


1. `$ xcode-select -p`


「/Library/Developer/CommandLineTools」と表示されれば正常。
「/Applications/Xcode.app/Contents/Developer」と表示されたらパスがおかしいので2へ。

2.`sudo xcode-select -switch /Library/Developer/CommandLineTools` を実行
3. 再度`xcode-select -p`を実行。
4. 「/Library/Developer/CommandLineTools」と出力されることを確認

上記対応後、無事git configできるようになった。

## ついでに
GitのUserNameを変更した場合のローカルの修正

#### UserNameの修正

```
$ git config --global user.name 'newUserName'
```
`$ git config --global -l`で確認。

#### リポジトリURLの修正

```
$ cd ローカルリポジトリ
$ git remote -v

# 変更前
origin  git@github.com:oldName/repository_name.git (fetch)
origin  git@github.com:oldName/repository_name.git (push)

$ git remote set-url origin git@github.com:new_name/repository_name.git
$ git remote -v

# 変更後
origin  git@github.com:newName/repository_name.git (fetch)
origin  git@github.com:oldName/repository_name.git (push)
```
pushの方がoldNameになっていたため下記を実行

```
$ git remote set-url --push origin git@github.com:new_name/repository_name.git
$ git remote -v

# 変更後
origin  git@github.com:newName/repository_name.git (fetch)
origin  git@github.com:newName/repository_name.git (push)
```

無事どっちも修正された。


## 参考

https://techracho.bpsinc.jp/hachi8833/2016_09_09/25454
https://dangerous-animal141.hatenablog.com/entry/2014/05/05/000000
CentOS, Ubuntu, DebianのDockerイメージ with SSH & SFTP

#はじめに
明けましておめでとうございます。
無事に年も明けてやっと少し落ち着きました。

今回は新年早々、自作Dockerイメージを公開してみます。
令和初元旦の記念投稿です。

##公開イメージ
Dockerの各種ベースイメージにSSHとSFTPの接続機能を追加したイメージです。
簡単な使い方も付けています。

- **CentOS 7, 8**
https://hub.docker.com/r/takeyamajp/centos-sshd

- **Ubuntu 16.04, 18.04**
https://hub.docker.com/r/takeyamajp/ubuntu-sshd

- **Debian 9(stretch-slim), 10(buster-slim)**
https://hub.docker.com/r/takeyamajp/debian-sshd

コメントやDocker Hubで星を付けて頂けると励みになります。すごく。
**2020/01/13にDebianイメージを追加しました。
Dockerfileのビルド過程や実行環境の解析に活用してください。**

##経緯
作成の経緯として、Dockerでの柔軟なビルドや調査にはベースイメージにsshdを追加したものが必須であるにも関わらず、世界中で各自が同じようなイメージを自作しているのが現状でした。
すでに誰かによって公開されているイメージを使うにしても、どこか動作が変だったりして結局は自分で調査して改良する事になります。

そのような不毛な車輪の再発明を終わらせるべく、これまでシンプルかつ信頼性の高いイメージの作成に取り組んで参りました。なんちゃって。

要するに、せっかく作ったので役に立つなら使ってください的な投稿です。
試しビルドの削減はもちろん、アイデア次第で色々と便利な使い方ができると思います。

###簡単な使い方 (Ubuntuの例)
- イメージの概要

```text
FROM ubuntu:18.04  

ENV TZ Asia/Tokyo
ENV ROOT_PASSWORD root

EXPOSE 22
```
- コンテナの起動例  
起動後は、使い慣れたSSHターミナルやSFTPクライアントからアクセスすることが出来ます。  
初期設定は root/root でログイン出来ます。  

基本的には、SSHターミナルでDockerfileのRUNブロックを順番にコピペするだけで、世界中で公開されているほとんどのイメージのビルド過程や実行環境を再現出来ます。

ENVは環境変数としてexportコマンドに置き換えます。
そして、Dockerfileから作成されたイメージの起動を再現するには、CMDの内容を引数にしてENTRYPOINTで指定されているファイルを実行します。
（ここまで来ると、凄まじくDockerfileへの理解が進む事でしょう）

```text
docker run -d --name ubuntu-sshd \  
       -e TZ=Asia/Tokyo \  
       -e ROOT_PASSWORD=root \  
       -p 8022:22 \  
       takeyamajp/ubuntu-sshd
```
必要に応じて、公開するポートやボリュームを追加することが出来ます。

通常ここで追加するのは、Dockerfileのexportやvolumeに記述されている内容になるでしょう。

```text
docker run -d --name ubuntu-sshd \  
       -e TZ=Asia/Tokyo \  
       -e ROOT_PASSWORD=root \  
       -p 8022:22 \  
       -p 8080:80 \  
       -v /my/own/datadir:/var/www/html \  
       takeyamajp/ubuntu-sshd
```

この例では、WEBサーバー関係を調査するために、追加でポート80とDocumentRootのディレクトリを公開しています。  
例えば、コンテナ内でapache2をインストールして`/usr/sbin/apache2 -DFOREGROUND `のようなコマンドを実行すれば、実際にブラウザーからアクセス可能なWEBサーバーとして機能させる事が出来ます。 
このようにして、Dockerfileを書いてビルドする前に、このコンテナで確認する事が出来ます。

- タイムゾーンには、Linuxで設定できるタイムゾーンをそのまま指定することが出来ます。  
海外在住な人も心配ご無用です。

タイムゾーンの一覧
https://www.unicode.org/cldr/charts/latest/verify/zones/en.html

- ログは「docker logs」に出力します。  
このコンテナへのSSH接続開始、認証、切断などの情報が出力されます。

次のコマンドでリアルタイムにログを参照する事が出来ます。

```text
docker logs -f ubuntu-sshd
```

以上です。
それでは今年も良いDockerライフを！