OmniAICreator/Qiita-1.07M huggingface dataset:
【Git】他のユーザーのレポジトリをローカルで操作する方法

複数人で共有しているプロジェクトで、他の人のコードを自分のローカルで確認したい時に使える方法。

Zoomで画面共有してもらって操作もできるけど、自分の環境に引っ張ってきた方が使い慣れたエディタで操作できる。


##1. リモートレポジトリの最新の状態をとってくる

・`$ git fetch --all`
すべてのブランチのコミットをとってくる。

```
$ git fetch --all

Fetching origin
remote: Enumerating objects: 442, done.
remote: Counting objects: 100% (410/410), done.
remote: Compressing objects: 100% (195/195), done.
remote: Total 323 (delta 191), reused 257 (delta 126), pack-reused 0
Receiving objects: 100% (323/323), 209.57 KiB | 171.00 KiB/s, done.
Resolving deltas: 100% (191/191), completed with 42 local objects.
From github.com:
 * c17c148..df285a3  master     -> origin/master
```

##2. gitをクリーンな状態にする
ブランチを移動する前に、ワークツリーの変更やステージングがない状態にする。

方法はいろいろあるので主要どころだけ。

```:コミットする場合
git add .
git commit -m "コミットメッセージ"
```

```:一時避難する場合
git stash -u
```

-uをつけると、untrackedfileも含めて差分を退避できる。


```:直近のコミットの状態にする（差分は削除）
git reset --hard origin/現在のブランチ名
```


##3. ローカルのリモート追跡ブランチに移動する

```
git checkout origin/移動したいブランチ名
```


##4. 作業用ブランチを作成する

```
git checkout ブランチ名
```

これで、リモートレポジトリの指定したブランチの状態がローカルに再現できた。


##5. masterの変更を取り込む
移動したブランチの作業よりもマスターが進んでいる場合があるので、環境を最新状態に合わせるため、masterのコミットを取り込む。

```
git rebase origin/master
```

以上でローカルで作業できる環境が完成。（エラーが出たら`git rebase --abort`で戻せる）


##6. ブランチの削除
作業が完了して不要になったら、ブランチを削除する。

```
$ git checkout master 
$ git branch -D 消したいブランチ名
```

削除前に、必要に応じてgit push origin ブランチ名でプルリク出すなど、そこら辺は状況に合わせて。


<br>
以上。
シェルのリダイレクト時に元ファイル名を利用する方法

#概要
シェルでデータを加工する際に、bashのパラメータ展開を利用することで拡張子だけ変えたりすることが出来ます。

##やり方
例えばcatで"temp.txt"を出力して、出力結果を"temp.csv"にしたい場合以下のようにします

```parameter.sh
data = temp.txt
cat $data > "${data%.*}.csv"
```


逆に、拡張子は変えず、ファイル名だけを変えたい場合は
`#*.`
を使えばよいそうです。
【Photon】Photonを自動起動するshell

#実行環境
エディション Windows 10 Pro
バージョン 20H2
インストール日 ‎2020/‎11/‎12
OS ビルド 19042.630
エクスペリエンス Windows Feature Experience Pack 120.2212.31.0


#管理者権限で以下を実行


```bash:photon自動起動
$Sta = New-ScheduledTaskAction -Execute "PhotonControl.exe" -WorkingDirectory "C:\Photon\bin_Win64\"
$STSet = New-ScheduledTaskSettingsSet
$Stt = New-ScheduledTaskTrigger -AtLogon
Register-ScheduledTask PhotonControl -Action $Sta -Settings $STSet Trigger $Stt -RunLevel Highest
```
【Python】Fontオブジェクトを使って文字の書式を統一する。

pythonを使用してExcelファイルの操作を勉強しています。
本日の気づき(復習)は、書式に関してです。
pythonでExcelを操作するため、openpyxlというパッケージを使用しています。

# Fontオブジェクト
文字の書式を設定するための使うのですが、想像以上に色々な引数が用意されていて
びっくりしました。

```python
cell.font = Font(name=フォントの名前, color=RGB形式の色, size=サイズ, bold=太字にしたい場合はTrue)
```
メインで使用するのはこれくらいでしょうか。

```python
class Font(name=None, sz=None, b=None, i=None, charset=None, u=None, strike=None, color=None, scheme=None, family=None, size=None, bold=None, italic=None, strikethrough=None, underline=None, vertAlign=None, outline=None, shadow=None, condense=None, extend=None)
```

こんなにあるの？？

- name           :フォント名を文字列で指定
- b（bold）      :ボールド体（太文字）Trueで太字、Falseで戻る
- i（italic）    :イタリック体（斜体）Trueで斜体、Flaseで戻る
- strike        :打消し線 Trueで打消し線、Flaseで戻る
- sz（size）    :文字の大きさ サイズを数値で指定（小数可能）
- u（underline）:アンダーライン4種類ある
- shadow        :文字に影をつける Trueで影がつくっぽいですが分からないです。
- vertAlign     :上付き下付き文字の変更3種類ある
- color         :色コード文字列で指定
- shceme        :文字が薄く？細く？なるmajorで細く、minorで戻る
- charset,family,outilne,extend,condense:わかりませんでした。

補足としては
u（underline）:アンダーラインの4種類は

1. 下線(文字列の長さ)：single
2. 二重線(文字列の長さ)：double
3. 下線(セルの長さ)：singleAccoounting
4. 二重線(セルの長さ)：doubleAccoounting

と
vertAlign     :上付き下付き文字の変更の3種類は

1. superscript：上付き文字
2. subscript：下付き文字
3. baseline：元に戻る

でした。

流石に記述だけだと慣れるまではイメージしにくいですね。
そういう意味ではＥｘｃｅｌ考えた人って偉大ですね。

```python
from openpyxl import load_workbook
from openpyxl.styles import Font

wb = load_workbook('商品リスト.xlsx')
ws = wb.active

# 文字の書式を生成
blue_font = Font(name='MS P明朝', color='0000FF', size=18, bold=True)

for row in ws['A1':'BB1']:
    for cell in row:
        cell.font = blue_font

wb.save('商品リスト_加工後.xlsx')
```

この様な記述で商品リストの最上段カラム名の部分の書式設定が出来ます。
JavaScriptの基礎知識２

# JavaScriptの基礎２
JavaScriptのアウトプット２回目です。

## 条件分岐
JavaScriptの条件式はrubyと少し異なる。
まず、条件式を書くときは( )の中に記述する。そしてtrueのときの処理を{ }の中に記述する。
条件式１がfalseだったとき、２回目の条件式を記述するときは else ifと記述する。rubyだったらelsifとなるところである。また処理は同じく{ }のなかに記述する。
条件式がすべてfalseだった時にelseとその処理を{ }のなかに記述する。

まとめてJavaScriptで条件分岐するときは以下のようになる。

```:js
if(条件式){
  条件式がtrueの時の処理
}　else if（条件式２) {
  条件式１がfalseで条件式２がtrueのときの処理
}　else　{
　条件式１と条件式２がfalseのときの処理
}
```

## 配列の要素を出力
配列の要素を出力したいときは次のように記述する。

```:js
const list = ["apple", "orange", "lemon", "grape"]
connsole.log(list) //リストすべてを出力
console.log(list[1]) //リストの中の1番目の要素を出力
```

## 繰り返し処理
for文を使って繰り返し処理を行うことができる
構文は次の通り

```
for ([1.初期化式]; [2.条件式]; [3.加算式])
```
第一引数の[1.初期化式]は今行われている処理は何回目の処理なのかを判定している。
第二引数の[2.条件式]はfor文の処理を何回行うかを指定する。返り値がtrueである限り繰り返し行われる。
例： i < 10 を記述すると変数iは１０より小さいときが続き限りtrueは出るのでそれまで処理は繰り返される。
第三引数の[3.加算式]は初期化式で定義した変数の増減を指定する。
例：i +=1と記述したなら処理が続くならiに１プラスされるということ。

## 配列の繰り返し処理
rubyでeach文に当たるものになるのが、for Each関数である。

```
配列 = ["A", "B", "C"]
配列.forEach(function(value){
console.log(value)
}
出力結果
A
B
C
```

以上です。
【VSCode】余計な空白を色付けして表示する方法と自動削除する方法（git diffの赤色表示をエディターに適用する）

git diffでコードをチェックした時に、不要なスペースが入っていると赤色で表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/2ff0364d-0b91-aa29-1e8c-f61644a67364.png)

これをコードエディタでも表示できるようにする方法。


<br>
##設定手順

拡張機能で`Trailing Spaces`を検索し、インストールすればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/a3dad3bf-396d-2cb7-572b-00310eeb1034.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/ad005d2d-bc3c-2bd3-f778-ad4b01d7608b.png)

git diffと同じように不要なスペースが赤色でハイライトされた。


##追加設定
settings.jsonを開き以下を追記すれば、機能を追加できる。

###settings.jsonの変更方法

(1) ctrl + shift + p　でコマンド入力窓を表示する。
(2) `settings.json`を入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/64fb9922-ef2d-d03b-dc76-e220290fe571.png)

(3) 「基本設定を開く」をクリック
(4) 指定のコードを追記する

```
{
  "workbench.iconTheme": "vs-minimal",
   
   省略
   
  "emmet.triggerExpansionOnTab": true,
  "editor.rulers": [80]
}
```

###ハイライトの色の変更

```
{ "trailing-spaces.backgroundColor": "rgba(255,0,0,0.3)" }
```

rgbaで色を指定できる。４つ目の数値は透明度。1が透過なし。0が完全透過。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/fa8b9c80-2ab1-8876-aeda-5a96ee031de2.png)


###自動削除
保存した時に自動で削除する。

```
"trailing-spaces.trimOnSave": true
```
STM32F767で脈拍センサー,AE-NJL5501Rので脈拍を見る


![pm_an_f767_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/0295f1a9-57e7-0480-1c07-de6d53e1bda2.jpeg)

1.センサーの接続
2.下記のソースコードを書き込む
3.コンパイル実行で表示されたら終了
4.Arduinoプロッターで開く
5.おわり

範囲を切り出しているだけなので
0または255に張り付くようならばプログラムを改造してね


秋月の脈拍センサー,AE-NJL5501Rで脈拍を見る NJL5501R
https://qiita.com/caa45040/items/f3a5674e825c9ac542fb


```c++

#include "mbed.h"

AnalogIn adc_vbat(A0);

DigitalOut led(LED1);

DigitalIn bu(PC_13);

int main()
{
    unsigned short aa;
    
    while( bu.read() == 0 ) { }
    
    while(1) {
        
        
        aa = (adc_vbat.read_u16()/16);
        if ( aa <= 1700 ) { aa = 0;} else { aa = aa - 1700; }
        
        aa = aa / 2;
        
        if ( aa >= 255  ) { aa = 255; }
        
        printf("%u\r\n", aa );
        //printf("%d\r\n",bu.read());
        //led = !led;
        if ( aa >= 128 ) {led = 1;} else {led = 0; }
        wait_ms(10);
    }
}



```
【VScode】指定した文字数に線を入れる方法（可読性の高いコードを目指して）

VScodeで指定した文字数に線（定規）を入れることができる。80文字というのが読みやすいコードの一つの目安になる。

このラインを越えるようなら改行する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/b05ab6cc-52bf-d168-8454-f9f5f1bcb1ce.png)


##表示方法
(1) ctrl + shift + p　でコマンド入力窓を表示する。
(2) `settings.json`を入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/64fb9922-ef2d-d03b-dc76-e220290fe571.png)

(3) 「基本設定を開く」をクリック
(4)　`"editor.rulers": [80]`を追記（線をひきたい文字数をカッコに入れる。）

```
{
  "workbench.iconTheme": "vs-minimal",
   
   省略
   
  "emmet.triggerExpansionOnTab": true,
  "editor.rulers": [80]
}
```

上の行末に`,`必須。下にも行が続く場合は、挿入した行の末尾に`,`をつける。



<br>
##ラインを複数引く方法
`[ ]`に複数の数値をカンマでつないで記載すれば、線を複数引くことができる。

```:例
"editor.rulers": [20, 40, 60, 80]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/7a4b4239-a512-9520-7528-7a1e8c951469.png)


<br>
以上。
Docker/docker-composeのインストールコマンド

---
#Dockerのインストール
```
sudo yum install -y docker
```
→Dokcerのインストール

```
sudo service docker start
```
→Dockerを起動

```
sudo usermod -G docker myuser
```
→dockerコマンドを権限なしで利用できるように設定します

```
exit
```
→再ログインしてからではないとエラーが発生してしまうため、一旦exitください

```
docker info

(↓このように表示されればOKです)
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
・・・
```


---
#docker-composeのインストール
```
sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
```
→docker-composeのインストール

```
sudo chmod +x /usr/local/bin/docker-compose
```
→docker-composeコマンドを実行できるように，実行権限を与えます

```
docker-compose --version
```
→バージョンが確認できればOKです。

---
##参考記事
[無料！かつ最短？で Ruby on Rails on Docker on AWS のアプリを公開するぞ。](https://qiita.com/at-946/items/1e8acea19cc0b9f31b98)
[dockerとdocker-composeのインストール(Linux編)](https://qiita.com/youtangai/items/ff67ceff5497a0e0b1af)

---
【PHP】比較演算子「==」の罠

# 読んでほしい人
いきなりですがPHPで**`'0です' == 0`** が**`true`**なのか**`false`**なのか迷った方ははぜひ見て下さい。
# はじめに
PHPで等しいかどうか判別をするときは**`==`**か**`===`**を使います。
**`==`**を使うとPHPは型の判定を行わず、値をなんかいい感じにキャストして比較をしてくれます。

例えば、
**`null == 0`**や**`'0' ==  0`**なんかは**`true`**になります。

このあたりは基本的な話なので、みなさん知ってるわ！って感じですよね。すみません。
しかし、比較演算子**`==`**の仕様にはもう少し罠があり、僕はまんまとハマってしまったので本記事でご紹介していきたいと思います。

# 比較演算子 **==** の罠


さっそくですが下記プログラムを実行します。

```php:

$zero = [0, null, '', '0', 'news zero', 'Re:ゼロ', '0じゃないよ', '１です'];

foreach ($zero as $value) {
    if ($value == 0) {
        print '0だよ' . PHP_EOL;
    } else {
        print '0じゃないよ' . PHP_EOL;
    }
}
``` 

このプログラム、どのような結果になると思いますか？
少し考えてみて下さい。




<details><summary>答え</summary>
ーーーーーーーーーー
0だよ
0だよ
0だよ
0だよ
0だよ
0だよ
0だよ
0じゃないよ
ーーーーーーーーーー
おそろしいことに`'1です'以外の結果はは全て'0だよ'になります`
'0'は分かるけど'news zero'や'Re:ゼロ'も0と判定されてしまうのには納得いきません。
しかも'1です'はしっかり'0じゃないよ'になるハチャメチャっぷり。</details>

# なぜこうなるのか

結論から言うと

* `[文字列] == [整数]`で比較をすると文字列は整数にキャストされる。
* 整数で始まらない文字列は全て0にキャストされる
* 整数で始まる文字列は、その整数にキャストされる

が理由です。

[公式ドキュメント](https://www.php.net/manual/ja/language.operators.comparison.php)には以下のように記載されています
>
オペランドが両方数値形式の文字列の場合、もしくは一方が数値で、もう一方が数値形式の文字列の場合、 比較は数値として行われます。 これらのルールはswitch文にも適用されます。型の変換は演算子が === や !== の場合は行われません。 なぜなら、これらの演算子は、値と型を両方比較するものだからです。


つまり、先程のプログラムだと
'news zero' → 0
'Re:ゼロ'     →　0
'１です' →　1
という感じでにPHPが勝手に変換しちゃってるんですね。
これって有効的に使える場面あるんだろうか...。

<font color="Red">ちなみに公式ドキュメントは、このような挙動になることを赤字でしっかり警告していました。</font>

それに気づかず、なんで文字列と0が同じなんだと困惑していた僕...。
みなさん、困ったときはまず公式ドキュメントをしっかり読みましょう。



# 最後に
今回の比較演算子の例に限らずPHPは型が曖昧でも動いてしまうので、変数や返り値の型をしっかり意識していきたいですね。

ちなみに、本記事で紹介した仕様はPHP8.0から変更されているようです。
下の記事が参考になるかと思うので、興味ある方はぜひ。
[【PHP8.0】非厳密な比較演算子`==`の挙動が今さら変更になる](https://qiita.com/rana_kualu/items/82cc8295d2102d14b88a)
インタープリタを作る その8

#概要

インタープリタを作ってみた。
九九やってみた。


#参考にしたページ


https://github.com/been-jamming/Ben-BASIC

#サンプルコード

```

>>> list
10 for i,1,9
20  for j,1,9
30   print i*j
40  end
50 end
>>>
```

以上。
ec2でのpullコマンドのエラー解決について


---
####エラー内容
```
git pull origin ブランチ名
```
を実行した際、

```
Enter passphrase for key '/home/ec2-user/.ssh/id_rsa': 
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```
とのエラーが発生する。

---

####解決法

こちらのサイトを参考にください。
分かりやすく丁寧に解説してくれています。

[【git エラー解決策】Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. が出た時の解決方法](http://tusukuru.hatenablog.com/entry/2018/08/29/021651)

---
####補足

ただ、上記説明記事にて、最後の「ssh -T git@github.com」が

```
Bad owner or permissions on /home/ec2-user/.ssh/config
```
とのエラーが発生された方は

```
chmod 600 ~/.ssh/config
```
を実行することで、「ssh -T git@github.com」が通るようになります。

ここまでくれば、git pullコマンドにてデータを持って来られるようになります。

---
####最後に

この記事が、同じエラーと闘う人の助けになりますように。

---
####参考記事

①[【git エラー解決策】Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. が出た時の解決方法](http://tusukuru.hatenablog.com/entry/2018/08/29/021651)
② [SSHコマンド実行時に生じたBad owner or permissions on /home/(user_name)/.ssh/config エラーの対処法](https://qiita.com/muramasa2/items/c58345b3ab6069d02849)
S3にアクセスしたらSSL証明書エラーになった原因

# エラー内容
S3のURLをhttpsにしてアクセスしたら、NET::ERR_CERT_COMMON_NAME_INVALIDが発生しました。

# 原因
アクセスしていた時のURLがhttpsの仮想ホスト形式で、かつドットが含まれるバケット名を使用していたため。

# 対応
パス形式に変更しました。

## 仮想ホスト形式とパス形式の違い
仮想ホスト形式（リージョン指定なし）
`http://[バケット名].s3.amazonaws.com`

パス形式（東京リージョンの場合）
`http://s3-ap-northeast-1.amazonaws.com/[バケット名]`

仮想ホスト形式はバケットがどのリージョンにあっても同じ形式でアクセス出来ますが、パス方式ではリージョン指定が必須です（バージニア以外）

## バケット名にドット（.）が含まれる場合は注意
ドットを含むようなバケット名はAWSも推奨していないので、使わないのが一番です。
[https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucketnamingrules.html](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucketnamingrules.html)

## パス形式は廃止されます
2020年9月30日以前に作成済みのS3バケットはパス形式廃止対象から除外されているようです。
いずれにしろ今後は仮想ホスト形式を使用するようにするのが良いと思います。

廃止の件などはクラメソさんの記事がわかりやすかったです。
[https://dev.classmethod.jp/articles/s3-path-deprecation-plan/](https://dev.classmethod.jp/articles/s3-path-deprecation-plan/)
Twitter APIのConsumer KeyとかCustomer Keyが見つからない時

TwitterのAPIを使おうとしてサンプルを沢山見ていたが、最近developerページのUIが変わったようで、Consumer Keyが見つけられなかった。
色々調べたら以下に答えがあった。

https://developer.twitter.com/ja/docs/authentication/oauth-1-0a/obtaining-user-access-tokens

![スクリーンショット 2021-03-11 18.56.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467051/7a98c027-21bc-041f-719a-a31caa678823.png)

###**ま　じ　か　よ**
つまり、この記事によると
App Key と API Key と Consumer API Key と Consumer Key と Customer Key と oauth_consumer_key は**同じもの。**
App Key Secret と API Secret Key と Consumer Secret と Consumer Key と Customer Key と oauth_consumer_secret も**同じもの。**
らしい。
API Keyなら持っていたので解決した。
インスタンス変数とrenderの関係性

・【`redirect_to`は`Route`→`Controller`→`View`の道筋を辿るもの、`render`は直接`View`に飛ぶもの】ぐらいに思ってた事象が一気に言語化できた
・インスタンス変数への不信感が無くなった
・やっぱりRailsは便利

####【ページ内リンク】
[０．環境](#０環境)
[１．動機](#１動機)
[２．目的は【@user.save】が失敗した時](#２目的はusersaveが失敗した時)
&emsp;[①@user.save失敗した"後"の流れ](#usersave失敗した後の流れ)
&emsp;[②@user.save失敗する"前"の流れ](#usersave失敗する前の流れ)
&emsp;[③全体の流れ](#全体の流れ)
&emsp;[④結論](#結論)
[３．じゃあ「def create」の「@user」を変えて試してみよう。しかし･･･](#３じゃあdef-createのuserを変えて試してみようしかし)
&emsp;[①別のにしても情報保持されたままになる！？](#別のにしても情報保持されたままになる)
&emsp;[②turbolinksを削除したら情報保持されないようになった](#turbolinksを削除したら情報保持されないようになった)

#０．環境
・AWS
・Rails 5.2.4.5
・ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]

#１．動機
下記において、
・「`newメソッド`内の`@user`」と「`createメソッド`内の`@user`」は別物なのに、何で同じ名前にしてるんだ･･･？
と思ったため、初心に帰って復習した


```rb:users_controller.rb
class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(name: params[:user][:name])
    if @user.save
      redirect_to どこでも好きな場所
    else
      render :new
    end
  end
end
```

```erb:/app/views/users/new.html.erb
<%= form_with model: @user do |f| %>
  <%= f.text_field :name %>
  <%= f.submit "登録" %>
<% end %>
```

[ページ内リンクへ戻る](#ページ内リンク)

#２．目的は【@user.save】が失敗した時
##①`@user.save`失敗した"後"の流れ
Ⅰ：`render :new`により`new.html.erb`が画面に表示される。
Ⅱ：終わり

･･･あれ、じゃあ何で入力した値は表示されたままなんだろう
って思ってたけど、`@user.save`の前に仕掛けがあったのか！

[ページ内リンクへ戻る](#ページ内リンク)

##②`@user.save`失敗する"前"の流れ
Ⅰ：`@user = User.new(name: params[:user][:name])`により`@user`に値が代入される（`save`はされていない）

そういえばRailsコンソールで遊んでた時も、バリデーション定めてたとしても`User.save`さえしなければどんな値でも入れられたなー。とか思った

[ページ内リンクへ戻る](#ページ内リンク)

##③全体の流れ
Ⅰ：`@user = User.new(name: params[:user][:name])`により`@user`に値が代入される（`save`はされていない）
Ⅱ：`render :new`により`new.html.erb`が画面に表示される。
Ⅲ：Ⅰで`@user`の`name`に値が入っているので、それが表示される

なるほど、`createメソッド`内の`@user`を別のインスタンス変数にしてたらⅢで何も表示されなくなるのか！
やっぱ何事もちゃんと理由あってやってるんだなと思った

[ページ内リンクへ戻る](#ページ内リンク)

#④結論
・`render`は
△【直接`View`に飛ぶもの】
〇【`Controller`→`View`の道筋を辿るもの】
ぐらいに思っておいたほうが良い？

・`resources: ～`において、`new`、`create`、`update`等は同じインスタンス変数を使うべきだと分かった。逆に、`destroy`ではわざわざ`@user`に値を代入する必要が無いことも分かった（値を再表示する必要が無い為）

[ページ内リンクへ戻る](#ページ内リンク)

#３．じゃあ「def create」の「@user」を変えて試してみよう。しかし･･･
##①別のにしても情報保持されたままになる！？
```rb:users_controller.rb
# 変更部分のみ
  def create
    user = User.new(name: params[:user][:name])
    if user.save

```
・このように`@user`を`user`に変えても情報が保持されたままになる
・では、上記で言ってることは誤りなのか

[ページ内リンクへ戻る](#ページ内リンク)

##②turbolinksを削除したら情報保持されないようになった
```erb:application.html.erb
↓</head>の上にあるこの1行(いわゆるturbolinks)を削除する
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
```
・これを削除したら情報保持されないようになった
・`turbolinks`は、ページ遷移の際、いちいち読み込みをする必要を無くす役割。(ページ遷移しても`更新ボタン`が変化しない)
・`turbolinks`導入していると、遷移前と遷移後のページが同じ場合、何も作動しないのと同じとなる？

※ちなみに`turbolinks`導入していると、**`｢render｣`を`｢redirect_to｣`に変えても情報保持される**ので注意

[ページ内リンクへ戻る](#ページ内リンク)
config/master.key: No such file or directory

---
####エラー内容
git clone後、scpコマンドにてmaster.keyをEC2へアップロードしようとした際に

```
config/master.key: No such file or directory
```
が発生してしまう。

---

####原因
ローカルにあるデータの「credentials.yml.enc」「master.key」と、EC2上にあるデータの「credentials.yml.enc」「master.key」が一致しないため、エラーが発生していました。

---

####解決法
①ローカルにあるcredentials.yml.enc(configディレクトリ内にあります)を削除ください。
→右クリックで直接削除しても問題ないです。

②ローカルのアプリケーションのルートディレクトリにて「 EDITOR=vim rails credentials:edit」コマンドを実行ください。
新たにcredentials.yml.encとmaster.keyが再生成されます。

③作成されたcredentials.yml.encとmaster.keyを保存(:wq)した後、
「scp -i ~/.ssh/practice-aws.pem config/master.key ec2-user@IPアドレス:アプリケーション名/config」コマンドを実行すると、EC2へ送信できます。

---

####最後に

私がこのエラーに出会した時、解決するまでにかなり時間がかかりました…。
この記事が、同じエラーと闘う人の助けになりますように。

---
静的サイトを作るときに調べたホスティングサービス一覧


#はじめに
静的サイトのホスティングサービスを調べたので各サービスの特徴を書きました。

#求めていること
- 静的サイト
- 独自ドメイン使用可能
- (できれば)無料で使える

#Netlify
- 基本無料でつかえる
- 商用利用可能
- 独自ドメイン可
- SSL対応
- 転送量100GB/月まで無料
- ビルドが300分まで無料
- CLIからの操作なら複数人操作可能
    - webコンソールでは1名のみ(無料枠)
- 情報量は多い

#Firebase Hosting
- 従量課金制
- SSL可
- 独自ドメイン可
- 転送量10GB/月まで無料
    - Netlifyの10分の1
- firebase analyticsとの連携は特にない
- 情報量は多い

#Gitlab P"#ages
- SSL可
- 独自ドメイン可
- 転送量無制限
- ビルドが1000分まで無料
- 公開、管理がNetlifyよりは手間がかかる
- 情報量は少ない

#Heroku
- 動的サーバがメインだが静的サーバ利用も可能
- １か月当たり1000時間まで無料で使える
- 商用利用可
- 独自ドメイン使用不可
- SSL非対応(無料枠の場合)
- 静的サーバ利用の情報量はそこまでない

#Github Pages
- 無料
- サイトを公開するにはリポジトリを公開しなければいけない



#結論
十分な転送量(100GB/月)と豊富な情報量がある「Netlify」を使おうと思います。

#さいごに
無料のホスティングサービスってたくさんあるんですね。
情報量が少ないからGitLab Pagesは見送りましたが、転送量無制限というのが魅力的なのでそのうち触ってみようと思います!


###プチ宣伝
**ひびきんぐ**([@hibiking3456789](https://twitter.com/hibiking3456789))といいます!
仕事と趣味の両方でXR三昧の日々を送ってます。

私たち[DENDOH Inc.](https://dendoh.co.jp/)ではARを用いた購買体験や、3Dクリエイター向けのサービスを開発しています。
一緒に働きたい方、学生でインターンしたい方をエンジニアに限らず募集しています！
興味のある方は[ひびきんぐ](https://twitter.com/hibiking3456789)のDMまでお声掛けください！

#参考サイト

- Netlify
    - [Netlify公式サイト](https://www.netlify.com/)
    - [【全部無料】静的サイトジェネレータ用・おすすめホスティング・サーバー](https://www.serversus.work/topics/fo9775eg66c4bx2sbsya/)
    - [Netlifyの使い方入門 無料料金枠や独自ドメイン設定方法について](https://simple-it-life.com/2020/08/30/netlify/)
    - [Netlifyのビルド時間制限(300分/月)は足りるのか](https://www.ultra-noob.com/blog/2020/2020-03-18-netlify%E3%81%AE%E3%83%93%E3%83%AB%E3%83%89%E6%99%82%E9%96%93%E5%88%B6%E9%99%90-300%E5%88%86-%E6%9C%88-%E3%81%AF%E8%B6%B3%E3%82%8A%E3%82%8B%E3%81%AE%E3%81%8B/)
    - [Netlifyをローカルでビルドしてからでデプロイする方法](https://kanau.page/0036/#:~:text=Netlify%E3%81%A7%E3%81%AE%E3%83%93%E3%83%AB%E3%83%89%E6%99%82%E9%96%93,%E5%88%86%E8%BF%91%E3%81%8F%E3%81%8B%E3%81%8B%E3%81%A3%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)
- Firebase Hosting
    - [Firebase公式サイト](https://firebase.google.com/pricing/?hl=ja)
    - [Firebaseの各機能を3行で説明する](https://qiita.com/shibukk/items/4a015c5b3296563ac19d)
- Heroku
    - [Heroku公式サイト](https://jp.heroku.com/)
    - [Heroku DynoのFreeプラン（無料プラン）はどこまで使えるか？](https://note.com/mikora_work/n/n1eddeae2266a)
- GitLab
    - [GitLab公式サイト](https://www.gitlab.jp/)
    - [GitLab Pagesで静的ウェブサイトを公開する方法](https://www.gitlab.jp/blog/2020/06/29/how-to-use-gitlab-pages/)
    - [BlogやるならGitLab Pagesがおすすめ](https://keens.github.io/blog/2020/03/27/blogyarunaragitlab_pagesgaosusume/)
    - [Gatsbyブログを無料で帯域無制限のGitLab Pagesに移したらいいことしかなかった](https://www.jabba.cloud/20200305-gatsby-gitlab/)
    - [GitLab Pagesの使い方｜無料でホームページを作成](https://www.boost-on.net/2551)
pythonのデータ型まとめ

# はじめに

pythonの関してすぐに忘れそうなので自分用メモを残します。

# 数値型

## 整数

整数値を扱う型です。

* 使用例

![整数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604076/0c8f2d43-fe2e-1b48-99ba-648a6c3ae290.png)

## 浮動小数点数

小数点以下の値も扱える型です。

* 使用例

![浮動小数点.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604076/029cb7ba-e693-8456-f478-65b66121522b.png)

## 複素数

複素数を扱う型です。
jの前に数値が無いとエラーとなるので注意。

* 書式

```
数値j
```

* 使用例

![複素数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604076/0e1a3a51-cd77-6c7b-3c26-a840d7dc2a91.png)

# 文字列型

文字列を扱う型です。
''と""は同意となります。
'''で囲むと改行した文字列を扱うこともできます。

* 書式

```
'文字列'

"文字列"

'''
文字列
文字列
'''
```

* 使用例

![文字列.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604076/fb88fc0a-c451-1392-85ca-82cef4c07f9f.png)

# 論理型

True or Falseを扱う型です。

* 使用例

![論理型.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604076/c4b0c016-b28d-e3ac-5f9d-a63c11fd362f.png)

# リスト型

いわゆる配列です。

* 書式

```
[値1, 値2, 値3, 値4,...]
```

* 使用例

![リスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604076/556ea3a1-c627-5c92-63a7-8016191ee292.png)


# 辞書型

値毎にキーが設定される配列です。
JSONを扱うときに便利です。

* 書式

```
{キー1:値1, キー2:値2,...}
```

* 使用例

![辞書型.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604076/dc8498bd-ae7e-d1d4-b739-4607ed4ee54a.png)

# タプル型

書換え不可なリスト型です。
辞書型のキーとして使用できます。

* 書式

```
(値1, 値2, 値3, 値4,...)
```

* 使用例

![タプル型.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604076/e24509bf-1291-9917-fd1c-92a974e95942.png)

# 集合型

値の集合です。
値の順序は保存されません。

* 書式

```
{値1, 値2, 値3, 値4,...}
```

* 使用例

![集合型.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604076/28c704e6-c504-9f7c-cced-f756a47a0c2f.png)

# おわりに

以上です。
あれから10年。

## About
東日本大震災発生からはや10年。筆者は当時劇団四季でライオンキングを観劇中だった。
当時は社会と関わる術を知らない小さな学生だったが、今は違う。
エンジニアとして情報発信をする術を知り、表現するための手段手法を修得した。

であるならば、この10年という節目に、1エンジニアとして何かしらのアクションを残しておきたいなと思った。
とは言っても、仕事の合間に1日で作れるものなどたかが知れてるので、
大層なものを一から設計するのではなく、今現在把握している技術スタックで手軽に作れるものを形にしてみた。

## 出来たもの

https://disaster-memories.com/

- サイト上に表示されているGoogleMap上のピンをクリックすると、その地点で発生した過去の厄災を知ることができる。
- 各厄災の詳細情報を知りたい場合は、外部ページへのボタンを押下することで詳細情報にアクセスできる。
- それだけ。公開するか迷ったがこういうのは積み重ねだと割り切る。

(Windows/Andoroid は未検証)

## 技術スタック

Githubリポジトリは[こちら](https://github.com/xlgorbylx/disasters-japan)

- Adobe XD
- Vue3 (@vue/cli 4.5.11)
- TypeScript
- Maps JavaScript API

まぁ前置き通り、大したものではない。
史実に基づく事象を扱う手前、自前で文章を用意するのではなく出典を明示した上で画像/文章を引用している。
各厄災のデータは一枚のYAMLファイルにまとめており、vue-cli-plugin-yamlを用いてVueファイル内で読み込み、v-forで出力している。
スマホユーザをメインユーザと想定して作ったので、閲覧の際はスマホで触ってみていただけると嬉しい。

## 感想

一つ一つの災害・厄災を調べていく中で、聞いたことのあるものもあれば初めて知る事象もあった。
どの厄災も発生地域の行政組織が何らかの形で記録を残していることが多く、日頃から興味を向けて調べてみると面白いかもしれない。

## REFERENCE

https://developers.google.com/maps/documentation/javascript/using-typescript
Widgetの生成を条件分岐（if文）でコントロールする



2021/3/16 ：　コメントの情報をもとに更新


#概要
FlutterのWidget制御で使えそうなTipsです。

Flutterを触り始めて2ヵ月程度ですが、
「ん？これどうなってんだ？」と少し詰まったところがありました。

同じように躓いた人の助けになれればいいなと思い投稿します。

#やりたいこと

Flutterでは、
すべてクラスやメソッドで画面側のコントロール（ウィジェット）を作成します。


「URLリンクのデータがあったら、URLリンク用のウィジェットを生成」
「データがないなら何もしない（ウィジェットのエリアは省略）」

こういうことがやりたかったんですが、ちょっとうまくいかなかった。

### イメージ（脳内）
if(model.url != null)
true：URL用widget生成あり
false：URL用widiget生成なし


### イメージ（コード）
```こうあってほしい.dart
children: <Widget>[
  // urlリンクがあればリンク文字列用のwidgetを生成したい
  if(model.meetingUrl != null){
   MeetingUrlTextLabel(urlText: model.meetingUrl)
  }// elseはいらない  
]

```

#なぜうまくいかなかったか

先ほどの「こうあってほしい.dart」のままではエラーになります。
理由としては、if文はステートメント扱いのためのようです。

簡単に言うと、
ステートメントでは値を返すことも、返さないこともできるのでダメってこと。（と理解しました）

Children:<Widget>内では、必ず1つのWidgetが返ってくる必要があります。
セミコロンが付いた文｛｝；の｛｝内は自由に記述できますよね。

ステートメントについてコチラを参考にしました（私がC#畑出身のため）
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/statements-expressions-operators/statements



対策としては、「即時関数を利用する」「三項演算子を使う」の２つがあります。


#即時関数を使う

```即時関数.dart
children: <Widget>[
 (() {
   if (model.meetingUrl != null) {
     return MeetingUrlTextLabel(urlText: model.meetingUrl);
    }
   })(),
 ]
```
ちょっとカッコがとんでもないことになっちゃいます。
ここでやっているのは、「単一のウィジェットが返ってくる即時関数」を定義しています。

ちょっとわかりにくいですね。
三項演算子に置き換えると、かなり可読性が上がります。


#三項演算子を使う
```三項演算子.dart
children: <Widget>[
 model.meetingUrl != null
  ? MeetingUrlTextLabel(urlText: model.meetingUrl)
  : SizedBox.shrink(),
]
```
割とシンプルにできました。

MeetingUrlTextLabelは自作のウィジェットクラスです。

三項演算子の場合、式なので値が必ず戻る必要があり、
真偽の両パターンで何か書かないといけません。

その場合は、SizedBox.shrink()で領域の無いウィジェットを返します。
Container等でも代用可能ですが、レイアウトに影響を与える可能性もゼロではないので
SizedBox.shrink()を使うのが一般的みたいです。

#[2021/3/16追記] collection ifを使う
コメントで教えていただいた情報で、
Dart 2.3 以降では if や for を使って collection内を組み立てられるようです。
https://dart.dev/guides/language/language-tour#collection-operators

Dartの静的解析のルールにもなっており、公式としてはcollection ifを推しているみたいです。

やっぱりDartの公式情報も見るのは大切ですね。
そら言語がDartなんだからそらそうだろって話なんですが、
Flutterの仕様を理解するので精一杯だったのです・・・。

というわけで、**三項演算子ではなく、こちらを使うようにしましょう**

```CollectionIf.dart
children: [
  // constを書くとウィジェットがキャッシュされてパフォーマンス的に良いらしい
  if (model.meetingUrl == null) const SizedBox.shrink(),
  if (model.meetingUrl != null)
    MeetingUrlTextLabel(urlText: model.meetingUrl),
],
```



#まとめ

ウィジェットコードと処理コードが全く同じところに書くというのは
私にとって新しい文化でした。

本業ではC#のコーディング規約やアーキテクチャ支援をやっており、
責務ごとのアーキテクチャ分割は当たり前だったので、最初は可読性の低さに戸惑ったものです。

とはいえ、それなりにウィジェットをクラスやメソッドで分割したりできるので
案外可読性よく書けるのかなと。


また、ステートメント諸々について、
もし詳しい方いらっしゃったら教えてくれると嬉しいです！
【Rails6】指定したキーワードだけのルーティング情報を調べる方法

#概要
指定したキーワードだけのルーテイング情報を調べることができる方法 

```
$ rails routes | grep　○○
```

○○：キーワード

#postを例にすると

```
$ rails routes | grep post
```

postに関するルーティンだけ表示できます。

```
root GET    /                     posts#index
posts POST   /posts(.:format)     posts#create
GET    /posts/:id(.:format) posts#checked
```

#メリット
限られたルーティング情報の方が、rails routesの全表示よりも、効率的に目的のルーティング情報を調べることができます。

また情報が多いとコーディングミスの元となる可能性も出てくるので、エラー回避をすることができます。

以上です。
Windows＋M5StickCでAmazon FreeRTOSのビルド（ESP-IDF v4.2）

Windows でビルドを試したのですが、色々ハマったなので、うまくいった手順を残しておきます。
ESP-IDF v3.x系だと自分の環境だと依存関係の問題がクリアできなかったため、諦めてv4.2系を試したところビルドできました。

# 準備

https://docs.espressif.com/projects/esp-idf/en/release-v4.2/esp32/get-started/windows-setup.html

こちらのサイトから、 `esp-idf-tools-setup` をダウンロードし、 **管理者権限** で実行しインストールする。
設定はデフォルトのまま。Python3, Gitなど必要なアプリケーションなどが一式インストールされる。




# FreeRTOSのビルド(Ninja)

AWSのFreeRTOSのリポジトリをCloneしてビルド＆Flashします。
クレデンシャル設定のためのコード修正は適宜おこなう必要がありますが、ここでは割愛します。
※aws_clientcredential_keys.h, aws_clientcredential.hの変更が必要です。

参考：https://docs.aws.amazon.com/freertos/latest/userguide/getting_started_espressif.html

```batch
git clone https://github.com/aws/amazon-freertos.git --recurse-submodules
cd amazon-freertos
vendors\espressif\esp-idf\install.bat
vendors\espressif\esp-idf\export.bat
cmake -DVENDOR=espressif -DBOARD=esp32_wrover_kit -DCOMPILER=xtensa-esp32 -S . -B ./build -DAFR_ENABLE_ALL_MODULES=1 -DAFR_ENABLE_TESTS=0  -GNinja
ninja -C ./build flash
```
Windows 10 で回復ドライブが作れなかった時の対処法

# 現状
「このPCでは回復ドライブは作成できません」「必要ないくつかのファイルが見つかりません」となり、
Windows 10 20H2で「 Windows RE の状態:         Disabled」となってしまったときの対処法。

```
C:\Windows\system32>reagentc /info
Windows 回復環境 (Windows RE) およびシステム リセット構成
情報:

    Windows RE の状態:         Disabled
```

# 手順
## Windows 10のISOを落とす
「Microsoft Windows and Office ISO Download Tool」（Microsoft公式サイトからのisoダウンロードヘルパー)などで、使っているOSのバージョンと同じISOを落とす。

## 7-zipでinstall.wimの中身を見る。[^3]
落としたisoをマウントする。
7zipなどで、sources/install.wimを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/87bc3760-f069-bef7-4f43-48d98676d1ad.png)

[1].xmlを開く。
xmlの整形サイトがあるので、それで整えると見やすい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/4d48c031-e823-bf20-8104-fd34ec6740f5.png)
あいでぃーが1だとわかります。

## winre.wimを取り出す
install.wim内の あいでぃー\Windows\System32\Recovery\
にあるwinre.wimを
C:\Recovery\WindowsREにコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/e51c05bb-2c0f-e9c2-a05a-d50e0d032d20.png)

## Windows REを有効にする[^2]
管理者権限で立ち上げたコマンドプロントで

```
C:\Windows\system32>reagentc /setreimage /path C:\Recovery\WindowsRE
ディレクトリは次に設定されています: \\?\GLOBALROOT\device\harddisk0\partition3\Recovery\WindowsRE

REAGENTC.EXE: 操作は成功しました。
```

とすれば完了。




## Paragon Backup & Recovery 17 Community Editionで怒られた際も、この手法が使える
コード 66 担った場合は、以下のように追加でコマンドを実行します。

```
C:\Windows\system32>reagentc /enable
REAGENTC.EXE: 操作は成功しました。


C:\Windows\system32>reagentc /info
Windows 回復環境 (Windows RE) およびシステム リセット構成
情報:

    Windows RE の状態:         Enabled
    Windows RE の場所:         \\?\GLOBALROOT\device\harddisk0\partition3\Recovery\WindowsRE
    ブート構成データ (BCD) ID: 707513d0-8247-11eb-a1c8-b0a460cf7b18
    回復イメージの場所:
    回復イメージ インデックス: 0
    カスタム イメージの場所:
    カスタム イメージ インデックス: 0

REAGENTC.EXE: 操作は成功しました。

```


```
mkdir - pC:\ProgramData\Paragon Software\Backup & Recovery 17 CE\storage\jdb
```


>
>427名無しさん＠お腹いっぱい。2020/03/03(火) 02:39:22.57ID:F6Qv153a0>>428
>>426名無しさん＠お腹いっぱい。2020/03/02(月) 21:13:06.59ID:lIKrXWR70>>427>>429
Backup & Recovery 17 Community Editionで試しにリカバリUSB作ろうとしたら、エラーコード 66 ディレクトリが見つかりませんってでて失敗する
もっと前のバージョンで試した時は上手くいったんだけどな

>reagentc /info で回復環境が有効に設定されているかをまず確認する
Windows ADKがインストールされていてリカバリーメディアの作成時に
そこへのパスが有効になっていて設定されているかを確認する
それでも作成できない時にはParagon を再インストールです

# 
# 
>429名無しさん＠お腹いっぱい。2020/03/03(火) 20:54:45.98ID:qb6+0ZdG0
・方法1
%ProgramData%\Paragon SoftwareにHard Disk Manager 17 Suiteフォルダが作られてるから
その下のstorageフォルダ以下を%ProgramData%\Paragon Software\Backup & Recovery 17 CEフォルダにコピー

>storage\jdbフォルダ(空)を作成しても可
>
・方法2
上の原因は%ProgramFiles%\Paragon Software\Backup & Recovery 17 CE\layout.ini
PRODUCT_NAME = "Hard Disk Manager 17 Suite"
↓
PRODUCT_NAME = "Backup & Recovery 17 CE"
に変更してやればstorage\jdbフォルダはBackup & Recovery 17 CE以下に作られ、Hard Disk Manager 17 Suiteフォルダも作られない

[^1]

#Ref
[^1]: 【パラゴン】 Paragon全般スレ part3
 https://egg.5ch.net/test/read.cgi/software/1513961461/318-n
[^2]: https://www.winhelponline.com/blog/extract-files-windows-10-iso-dvd-install-wim/
[^3]: https://www.winhelponline.com/blog/extract-files-windows-10-iso-dvd-install-wim/
【2022年版】Solaris10 メモ

## はじめに
2021年でSolaris10をいじっている際のメモ。
様々な情報がGoogleすると存在するが、古くて使えないものも多かったので、2021-2022年版としてメモ。

## Solaris10 のドキュメント

[Oracle Solaris 10 1/13 Information Library (日本語) ](https://docs.oracle.com/cd/E38900_01/index.html)
[富士通公式 コマンド集(Oracle Solaris/XSCF)](https://www.fujitsu.com/jp/products/computing/servers/unix/sparc/technical/command-reference/)

## ユーザ追加

```shell-session
# useradd -m -d /export/home/{ユーザ名} -s /usr/bin/bash {ユーザ名}
```

## 現在のユーザの表示

```shell-session
# id
```

## ログインユーザの表示

```shell-session
# who
```

## シャットダウン

```shell-session
# halt

# poweroff

# init 0

# init 5

# shutdown -i0 -g0 -y
```

## 再起動

```shell-session
# reboot

# init 6

# shutdown -i0 -g0 -y
```

## シングルユーザモード

```shell-session
# init S
```

## ネットワーク設定

* ホスト名 
/etc/nodename に記述

* ipアドレス
/etc/{ホスト名}.{インターフェイス名} に記述
/etc/hosts に記述(/etc/inet/hosts, /etc/inet/ipnodes)
/etc/netmasks に記述(/etc/inet/netmasks)

* デフォルトゲートウェイ
/etc/defaultrouter

* ネームサーバ
/etc/resolv.conf

```file:/etc/resolv.conf
nameserver 8.8.8.8
nameserver 1.1.1.1
```

* ネームサービススイッチ（名前解決優先順位）

```file:/etc/nsswitch.conf
hosts: dns files
```

## パッケージマネージャで OpenCSW を使う

```shell-session
# pkgadd -d http://get.opencsw.org/
# /opt/csw/bin/pkguti -U
```

## パッケージの検索

```shell-session
# pkgutil -a {パッケージ名}
```

## パッケージのインストール

```shell-session
# pkgutil -y -i {パッケージ名}
```

## パッケージのアップデートチェック

```shell-session
# pkgutil -U
```

## パッケージのインストール済みと最新のチェック

```shell-session
# pkgutil -c
```

## パッケージのアップデート

```shell-session
# pkgutil -y -u {パッケージ名}
```

## パッケージのアンインストール

```shell-session
# pkgutil -r {パッケージ名}
```

## vim を使えるようにする

```shell-session
# /opt/csw/bin/pkgutil -y -i vim
# /usr/sbin/pkgchk -L CSWvim
```

## shellをbashに変更

```shell-session
# vi /etc/passwd
- hoge:x:100:1::/export/home/hoge:/usr/bin
+ hoge:x:100:1::/export/home/hoge:/bin/bash
```

## sudo を使えるようにする

```shell-session
# pkgutil -i sudo
# sudo -e /etc/opt/csw/sudoers
+ hoge ALL=(ALL:ALL) NOPASWD: ALL
```

## visudo の代わり

```shell-session
# sudo -e {ファイル}
```
## サービス

* ステータス表示

```shell-session
# svcs -xv {サービス名}
```

* サービス状態のクリア

```shell-session
# svcadm clear {サービス名}
```

* 再起動

```shell-session
# svcadm restart サービス名
```

* サービス設定の読み込み

```shell-session
# svcadm refresh
```

* 有効化

```shell-session
# svcadm enable {サービス名}
```

* 無効化

```shell-session
# svcadm disable {サービス名}
```

* 一時的に無効化

```shell-session
# svcadm disable -t {サービス名}
```

## GUIログイン

* GUIログインを無効

```shell-session
# svcadm -v disable cde-login
```

* GUIログインを有効

```shell-session
# svcadm -v enable cde-login
```

## CD-ROM/DVD-ROM

### 読み込み

- CD-ROM/DVD-ROM を挿入すると ```/cdrom``` に自動的にマウントされる

### 取り出し

```bash
#eject cdrom
```

## HDDの列挙

### fdsik

```bash
-bash-3.2# format < /dev/null
Searching for disks...done


AVAILABLE DISK SELECTIONS:
       0. c0t0d0 <LENOVO-X-ST91000640SS-LD2L cyl 41548 alt 2 hd 32 sec 1469>
          /pci@0,600000/pci@0/pci@0/scsi@0/sd@0,0
       1. c0t1d0 <LENOVO-X-ST91000640SS-LD2L cyl 41548 alt 2 hd 32 sec 1469>
          /pci@0,600000/pci@0/pci@0/scsi@0/sd@1,0
Specify disk (enter its number): 
```

### iostat

```bash
-bash-3.2# iostat -En
```
enumを使って難易度を変更するサンプルコード

`enum`を使って難易度を管理するサンプルコードです。
次の難易度があるかないかで変更ボタンを表示/非表示切り替えます。

`enum`Int型の`rawValue`で管理した方が変更がしやすい。
但し、全て`switch`地獄に陥りやすいので、

・`case`間を行き来したいか
・条件を網羅させたいか
・別カテゴリが含まれていないか

などを意識して使う必要がある。
必要に応じて`enuｍ`ではなく`protocol`と`struct`を組み合わせたものを使う。


```swift
import UIKit

class ViewController: UIViewController {

    private var mode = Mode.Normal

    @IBOutlet weak var modeLabel: UILabel!
    @IBOutlet weak var nextModeButton: UIButton!
    @IBOutlet weak var previousModeButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        modeLabel.text = mode.returnTitle()
    }

    @IBAction func didTapNextModeButton(_ sender: Any) {
        mode = mode.nextMode() ?? mode
        modeLabel.text = mode.returnTitle()
        nextModeButton.isHidden = mode.nextMode() == nil
        previousModeButton.isHidden = mode.previousMode() == nil
    }

    @IBAction func didTapPreviousModeButton(_ sender: Any) {
        mode = mode.previousMode() ?? mode
        modeLabel.text = mode.returnTitle()
        nextModeButton.isHidden = mode.nextMode() == nil
        previousModeButton.isHidden = mode.previousMode() == nil
    }
}

enum Mode : Int{

    //難易度を3つ用意
    case Easy
    case Normal
    case Hard

    func nextMode() -> Mode?{
        Mode(rawValue: self.rawValue + 1)
    }

    func previousMode() -> Mode?{
        Mode(rawValue: self.rawValue - 1)
    }

    //難易度毎のタイトルを返す
    func returnTitle() -> String {
        switch self {
        case .Easy:
            return "Easy"

        case .Normal:
            return "Normal"

        case .Hard:
            return "Hard"

        }
    }
}
```
terraform + aws + MFA + assuemRole を環境変数で済ませる方法

# Overview

terraform と MFA は相性が悪くて、 aws-vault でキーチェーンに認証情報保存したりしないとならないのがめんどくさいので、

https://dev.classmethod.jp/articles/terraform-assumerole/

環境変数でもうちょいカジュアルに済ませたい話。

# やり方

`aws sts assume-role` すると一時認証情報が返ってくるので、これを環境変数に設定する。

```json:sts.jq
.Credentials
| "AWS_ACCESS_KEY_ID=\(.AccessKeyId)"
, "AWS_SECRET_ACCESS_KEY=\(.SecretAccessKey)"
, "AWS_SESSION_TOKEN=\(.SessionToken)"
```

`aws sts assume-role` 時に MFA のパスワードを求められるので、まとめるとこう。

```bash:bash
$ export $(aws --profile your_admin_role sts assume-role --role-arn arn:aws:iam::000000000000:role/your_admin_role --role-session-name hogehoge | jq -r -f sts.jq)
Enter MFA code for arn:aws:iam::000000000000:mfa/hogehoge: (←パスワード入力)
```

## MFC だけ先に入力する

一度パスワード入力しておけばしばらく入力不要になるので、先に

```bash:bash
$ aws --profile your_admin_role sts get-caller-identity
Enter MFA code for arn:aws:iam::000000000000:mfa/hogehoge: (←パスワード入力)
```

とかで済ませておいてもいいかも。


# 確認

```bash:bash
$ aws sts get-caller-identity
{
    "UserId": "AAAAAAAAAAAAAAAAAAAAA:hogehoge",
    "Account": "000000000000",
    "Arn": "arn:aws:sts::000000000000:assumed-role/your_admin_role/hogehoge"
}
```

# 解除

token が expire すると使えなくなるので、環境変数を消すやり方。
新しい shell 立ち上げてもいいけど。

```bash:bash
$ unset $(compgen -v | grep AWS_)
```
Next.js typeScript型エラー

ここのhandlerに下記のようなエラーが出てきました。
型エラーだと思いますが、解決できなくて困っています。

```
型 '(req: any, res: any, name: any, password: any) => Promise<void>' を型 'NextApiHandler<any>' に割り当てることはできません。ts(2322)
```

```
const handler: NextApiHandler = async (req, res,  name, password) => {
  const salt = crypto.randomBytes(16).toString('hex')
  const hash = crypto
  .pbkdf2Sync(password, salt, 1000, 64, 'sha512')
  .toString('hex')
```
Apache antについてのメモ書き

古いJavaプロジェクトでantを使っているものがあり、調べた結果を記載する。

# 1. Antのバージョン
バージョンは1.9系と1.10系の2つがあり、1.10系はJava8が必要。
1.9系はJava1.5以降。
https://ant.apache.org/faq.html#java-version

JDK1.7のプロジェクトで、Eclipse(Pleeades)Antが1.10のため、JDK1.7でコンパイルすると
『JRE version less than 1.8 is not supported.』とエラーが発生する。

# 2.Eclipseに含まれるAntのバージョン

|Eclipse|Ant|
|:---|:---|
|4.5.2| 1.9|
|2018|1.10|
【Ubuntu 16.04】resolv.confが保存されない問題

#はじめに
本記事は前記事の続きです。

https://qiita.com/arakawada/items/0d3bc6cd54c000cf095d

resolv.confを書き換えましたが、PCを再起動すると変更が強制的に書き換わってしまいます。

#解決方法
調べてみるとNetworkManagerが起動時に上書きしている可能性があるらしい。
そこでNetworkManagerの設定を変更します。

エディタで開く。

```terminal
$sudo gedit /etc/NetworkManager/NetworkManager.conf
```

既存設定をコメントアウトし、dns=noneを追加する。

```/etc/NetworkManager/NetworkManager.conf
[main]
plugins=ifupdown,keyfile,ofono
#dns=dnsmasq  #既存設定をコメントアウト
dns=none      #この行を追加

[ifupdown]
managed=false
```

保存したら前記事の手順でresolv.confを編集した後、PCを再起動。
resolv.confが変更されていなければOK。

#あとがき
私の環境ではルーターのDHCPが動いているせいか、resolv.confがルーターのアドレスに書き換わってしまいました。
しかし、名前解決できない問題は解決したので、とりあえず今回はこれで良しとします。
Guardを使ってSwiftGenのビルドの手間を省く


[SwiftGen](https://github.com/AliSoftware/SwiftGen)、便利ですよね。
[Guard](https://github.com/guard/guard)を使って更に便利にしましょう。

# 前提
SwiftGenはアプリで扱う画像やストーリーボードなどのリソースをソースコードで安全に参照できるようにするライブラリです。
Guardはファイルの変更を監視して特定のタスクを実行するためのツールです。
それぞれの詳しい説明はここでは省きます。
使ってるもののバージョンは以下の通りです。

- XCode(12.2)
- Cocoapods(1.10.1)
- SwiftGen(6.4.0)
- Guard(2.16.2)

# SwiftGenはビルドしないと更新されない?
SwiftGenの[ドキュメント](https://github.com/SwiftGen/SwiftGen/blob/stable/Documentation/Articles/Xcode-Integration.md)で書かれているようにBuildPhasesにスクリプトを追加すると、ビルドの度にSwiftGenがコードを自動生成してくれるようになります。
ただしこれはビルドしないと実行されないため、変更したリソースをアプリのソースコードから参照するには一度ビルドを通す(あるいは手動でコンソールから./switgenを実行する)必要があります。
ここにGuardを導入し、リソースが変更されるとSwitGenが自動で更新を行う仕組みを作りましょう。

# Guardの導入
以下のようなswitgen.ymlが設定されているプロジェクトにGuardを導入してみましょう。

```yaml
xcassets:
  inputs: SampleApp/Assets.xcassets
  outputs:
    templateName: swift5
    output: SampleApp/Assets.swift
```

## インストール
以下のコマンドを叩いてGuardをインストールします。

```bash
$ gem install guard # Guardをインストール
$ gem install guard-shell # Guard::Shellをインストール
```

## Guardfileの設定
アプリのプロジェクトフォルダに移動し、Guardfileを作成します。

```bash
$ cd path/to/SampleApp # プロジェクトフォルダに移動
$ vi Guardfile # Guardfileを作成
```

Guardfileの内容は以下の通りです。
この例ではAssets.xcassetsを監視対象としています。プロジェクトに応じて適宜監視対象を書き換えてください。

```ruby
guard :shell do
  watch(%r{SampleApp/Assets.xcassets/(.*)}) { `./Pods/SwiftGen/bin/swiftgen` }
end
```

## 自動更新
以下のコマンドでGuardによる監視が始まります。
ここまでの設定が上手く出来ていればAssets.xcassetsが変更される度に自動でAssets.swiftが更新され、即座にアプリからリソースが利用可能になるはずです。

```bash
$ guard
```

これでアプリに画像やカラーパターンを追加する度にすぐにソースコードから参照可能になりました。
一度ビルドを走らせたりコマンドを叩く必要がなくなり作業がスムーズになるはずです。
[Django]関数ベースビューとクラスベースビュー

#はじめに
Djangoのビューを今まで関数ベースビューメインで書いていましたが､
今回はDjangoフレームワークが用意しているビュー用の親クラスを継承しクラスベースのビューを作成したいので両者を簡単にまとめました｡

##関数ベースビュー
関数ベースビューは以下のような構造をしています｡

```app/views.py
def hoge(request):
  [内部処理]
  return HTTPレスポンス
```
以下実例です｡

```app/views.py
def view(request):
  if request.method=='POST':
    form=HogeForm(request.POST)
    if form.is_valid():
      form.save()
      return redirect('hoge')
  else:
    form=HogeForm()

  context = {
      'form': form,
  }
  return render(request,'hoge.html',context)
```
hoge.htmlというテンプレートをロードし､contextという辞書変数にテンプレート変数名とその値を格納し､
renderクラスでテンプレートをレンダリングしその結果をHTTPResponseとして返します｡
HTTPResponseを行うクラスはrender,redirect,TemplateResponseの3つ｡詳しくは[ここ](https://qiita.com/taole33/items/1dfc0d46462c9e512385)

##クラスベースビュー
Djangoフレームワークで用意されたビュー用の親クラスを継承し使用します｡

```app/viwes.py

class View(LoginRequiredMixin,FormView):
  template_name='hoge.html'
  form_class=HogeForm
  success_url=reverse_lazy('hoge')

  def get_context_data(self, **kwargs):
       context=super().get_context_data(self, **kwargs)
       return context

  #formでの入力が正常であった場合に呼ばれる
  def form_valid(self,form):
    form.save()
    messages.success(self.request, "success")
    #return HttpResponseRedirect(self.get_success_url())
    return render(self.request,'hoge',self.get_context_data())
 ```
cotext変数→get_context_data関数
HTTPResponse→form_valid/form_invalid関数
と対応しています｡

なお､クラスベースビューはurls.pyに登録する際はpathの第2引数は関数を渡す必要があるためView.as_view()のようにします｡

```app/urls.py
urlpatterns=[
  path('hoge/',View.as_view(),name='hoge')
]
```

##まとめ
クラスベースビューは関数ベースビューを汎用化してくれているためたくさん定義する場合はできる限りクラスベースビューで書くのがいいかなと個人的に思います｡

##参考サイト
https://ebi-works.com/django-view/
https://docs.djangoproject.com/ja/3.1/intro/tutorial03/
Progateとドットインストールはどっちがいいの？

#Progateとドットインストール比較

TECH::CAMPの学習を終えて、現在は復習とさらなる深堀りをしている最中です。

今回はそんな中、Progateとドットインストールの2つのサイトで思ったことをまとめてみます。



`Progate`と`ドットインストール`はそれぞれ得意分野が違う
>
両方の良いところを抜粋して勉強するのがおすすめ？

| Progate | | ドットインストール |
|:-:|:-:|:-:|
| 超初心者 | 難易度 | 初心者 |
| 不要 | 環境構築 | 必要 |
| WEB教材 | コンテンツ | 動画教材 |
| 少ない | コース数 | 多い |
| 少ない | 質問対応 | 可能 |



1. Progateを使ってプログラミング言語に触れる
2. ドットインストールを使って開発環境を構築する

3. Udemy を使ってWebアプリケーション開発に挑戦する

>
Udemyは触れたことがないのでわからないですが…


## 短期間ではあるが活用してみた感想
環境構築不要、プログラミングの基礎から応用をスピード重視で勉強できる

###Progate
- 初心者が取っ掛かりやすい
- 環境構築不要
- 基礎~応用を`スピード重視`で学習可能
- 有料版は月額980円

ProgateのHPは[こちら](https://prog-8.com/dashboard)から

![Progate](https://markup-media.com/wp-content/uploads/2020/12/progate01.jpg)

>
開発環境（エディターなど）を特別準備をしなくて良い点が個人的に◎

###ドットインストール
- 環境構築から学習
- 基礎~応用を`動画教材`で学習可能
- 有料版は月額980円

ドットインストールのHPは[こちら](https://dotinstall.com/)から

![ドットインストール](https://markup-media.com/wp-content/uploads/2020/12/dotinstall.jpg)

>
実践的な知識を定着させるために、自身の開発環境を整える事ができる点が個人的に◎

#比較結果
結論としては`ハイブリット`がいいかな？と思っています。
>
触りだけ[Progate](https://prog-8.com/dashboard)でやってみて、更に定着させて実践に活かしたいのであれば[ドットインストール](https://dotinstall.com/)をしようする。

ただ、やることが決まってもやり続ける環境を作ることが一番難しいとは思うのですがね
python asyncio func Aが終わらない場合はfunc Bを追加し続ける

python 3.9.2

asyncio.キューはよくわからんし使いたくないので、それ以外の方法でタスクを追加し続けるやつ

```python
import asyncio

async def run_in_executor_A():
    #メインで長時間かかる処理
    def A():
        #一般的な処理
        print("Aを実行")
        sum([i*i for i in range(10**8)])
    loop = asyncio.get_running_loop()
    await loop.run_in_executor(None, A)

async def run_in_executor_B():
    #Aが終わらない時に追加で処理したい
    def B():
        #一般的な処理
        print("Bを実行")
        sum([i*i for i in range(10**7)])
    loop = asyncio.get_running_loop()
    await loop.run_in_executor(None, B)




async def stack_Deal():
    #run_in_executor_Aというコルーチンを生成、タスクとして走らせる
    MainTask=asyncio.create_task(run_in_executor_A())
    #タスクに名前を付与
    MainTask.set_name("タスクA")
    while 1:
        await asyncio.sleep(1)
        active_tasks = [task.get_name() for task in asyncio.all_tasks()]
        print(active_tasks)
        #タスクAが終了している場合は他のタスクを全て終了してループをbreak
        if not "タスクA" in active_tasks:
            for task in asyncio.all_tasks():
                if "タスク" in task.get_name():
                    task.cancel()
            break

        #タスクBが存在しない場合はrun_in_executor_Bのコルーチンを生成してタスクとして走らせる
        if not "タスクB" in active_tasks:
            TaskB=asyncio.create_task(run_in_executor_B())
            TaskB.set_name("タスクB")

if __name__ == '__main__':
    asyncio.run(stack_Deal())

```
実行結果

```
Aを実行
['Task-1', 'タスクA']
Bを実行
['Task-1', 'タスクB', 'タスクA']
['Task-1', 'タスクA']
Bを実行
['Task-1', 'タスクB', 'タスクA']
['Task-1', 'タスクA']
Bを実行
['タスクA', 'Task-1', 'タスクB']
['タスクA', 'Task-1', 'タスクB']
['タスクA', 'Task-1']
Bを実行
['タスクA', 'Task-1', 'タスクB']
['タスクA', 'Task-1', 'タスクB']
['タスクA', 'Task-1']
Bを実行
['タスクA', 'Task-1', 'タスクB']
['タスクA', 'Task-1', 'タスクB']
['Task-1']
```

asyncio.all_tasks()はすべての実行中のタスクを表示するので、ネスト的にあんまりよくない

stack_Dealが非同期関数である以上
stack_Deal()もコルーチンとなるため
asyncio.run(stack_Deal())もタスクとして表示される
タスクの名前は'Task-1'から自動的に振られていく

なので'Task-1'内部で'Task-1'をcancelしてしまうとバグるので
この処理方法はネスト的にあんまりよくない（小泉構文）

随時タスクを追加していく方法であって、別スレッドで処理する方法ではないので注意
【Ubuntu 16.04】有線接続が切れるというより名前解決ができない問題

#環境と症状
Ubuntu 16.04を使っていたが、ある時から有線接続が切れる？ようになった。
PCはリモートで操作することがほとんどだが、不思議なことにリモート接続はできる。
LAN内ではVNC、LAN外からはリモートソフトを使って接続しており、こちらは問題ないく使える。
リモート操作ができるということはインターネット接続はできているはずだが、ブラウジングすると「○○を解決しています．．．」のままだったり、やaptでダウンロードしようとすると0%のまま進まなかったりする。

適当なwebサイトのurlに対してnslookupやpingを走らせてみてもエラー表示。そもそも自PCから出れていないみたい。![p0.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459904/42043754-b86a-5f29-d76d-e414c2e7448d.png)


#とりあえずの対処
デフォルトでは右上にある有線接続をクリックすると数秒間だけ繋がる。
![SnapCrab_Ubuntu 64 ビット 1604 2018 - VMware Workstation 14 Player (非営利目的の使用のみ)_2021-3-9_17-57-59_No-00a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459904/9a973456-6175-cd18-7ac5-22da88497d20.png)

ブラウザでリンクをクリックしたりaptで接続をかけにいってからクリックすると、その接続はできる感じ。
この症状から名前解決ができていないと確信したのでDNSの設定をチェックする。

#設定の確認
設定->ネットワークからIPv4の設定を確認する。
DNSがおかしいので「追加のDNSサーバー」にゲートウェイになっているルーターのアドレスやパブリックDNS(8.8.8.8)を指定してみるが、症状は変わらず。
![p1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459904/9c542342-4159-22ff-db57-66de78ac2ba4.png)
※スクリーンショットではDHCPになっていますが、手動設定でも同じ結果でした。

#解決方法
/etc/resolv.confにDNSサーバーのアドレスを明記すればいいらしい

エディタで開く

```
$sudo gedit /etc/resolv.conf
```

8.8.8.8を指定

```/etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 8.8.8.8
```

保存すると名前解決できるようになった。
しかし、私の環境では再起動すると設定がリセットされてしまう。

この問題については次回。

###追記
続きを書きました。

https://qiita.com/arakawada/items/54db843c9f7339a468ef
#2 Pythonの冗長化した処理の解決 ｜リーガテックの神を目指す駆け出しITコンサルがインフラエンジニアに転身するまで

###前回記事

https://qiita.com/nyaku/items/1d48e4d8d552976b8642

### 今回のテーマ

今回は、前回、コードをみて明らかになった**冗長性問題の解決**に取り組みます。
といっても私が勝手に「問題」と位置づけているだけで、ちゃんと動いているのですが……笑

### 計画の概要

![スクリーンショット_2021-03-08_21_56_16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319381/1d5ee15c-531d-c1c5-946b-01e5faada675.jpeg)

前回登場したこのコードですが、GASに入っている同じワークブックから、変数`SP_SHEET`に入れるシート名がハードコーディングされている以外は全く同じ処理ですから、ハードコーディングされている部分を引数化してモジュールにすれば、処理部分の冗長性が解消できるのではないか、と思いました。

さっそく構造的に考えてみましょう！

#### 構造設計

| 現モジュール名 | 変数`SP_SHEET` | 戻り先 |
|:-:|:-:|:-:|
|  `auth_tunnels` |  'tunnels' | `worksheet_tunnels`  |
|  `auth_database` |  'database' | `worksheet_database`  |

こうなっているのを、
1. `SP_SHEET`の中身は呼出し時に引数で渡し、
2. 戻り先は代入先として呼出し時に前置しておく

と改めたいと思います。

#### 実装
![スクリーンショット_2021-03-11_15_12_04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319381/ee6c4cf3-94ea-dba9-52c5-ce2aaf008e9f.jpeg)
こんなふうになりました！

計画通り、スプレッドシートの参照先シート名を引数化して、ハードコーディングを解決。

###次回予告

次は、**現在の実行環境であるherokuの理解**を目指します！そしていよいよAWSへの移行へ！
a-blog cms WebP画像対応

# WebP画像対応しようと思って、設定したんだけど生成されなかった。

WebP画像対応しようと思って、以下に従って設定したんだけど生成されませんでした。
https://developer.a-blogcms.jp/document/reference/webp.html

# 画像エンジン変更で解決
そういえば、使ってるサーバーのImageMagickではWebP非対応だったと思い出し、以下を参考にImageMagickをoffにしたら無事に生成できました！やったね！！
https://developer.a-blogcms.jp/document/trouble-shooting/entry-2895.html

単純な話ですが、また同じことがあった時のために自分メモでした。