OmniAICreator/Qiita-1.07M huggingface dataset:
sliceとspliceメソッドの違いについて

# この記事の目的
  - **sliceとspliceメソッドの違いをイメージで大まかに理解する**
  - **引数の指定の仕方の違いを理解する**
  - **返値の違いを理解する**

JavaScriptを学び始めて、配列や文字列に使うメソッドである**sliceと spliceの違い**について、どっちがどっち？引数の指定の仕方が少し違ってた気がするけど、どうだったっけ？と何度か調べ直すことがありました。
**記憶を定着させて、調べ直す必要がなくなるようにするため**に、自分なりに違いを**ストーリー仕立て**にしてまとめてみました。

ここでは、配列に対する処理を考えます。まず、**配列を一本のロープに見立て**ます。

# slice
- **構文: slice(start, end)**

　　*スライサー*から想像できる通り、ロープを**必要な長さだけ切り取りたい時**に使います。このメソッドは、失敗しないように元のロープと同じ長さのロープを用意して切ってくれます。
　　切り取るには、どこからどこまで切り取るのかという情報が必要です。そのため引数は**取り出す起点(start)と終点(end)のインデックス番号**を定めます。
　ロープを切る時、終点にマジックで印をつけます。切り取った後のロープにマジックの印は不要なので、終点(end)は含みません。


- **返値 : インデックス番号endは含まず、start番目から(end - 1)番目までの要素を含む新しい配列**
- **元の配列: 変わらない**


[参考: sliceのMDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)


# splice
- **構文: splice(start, deleteCount, item)**

　　sliceを改良してさらに便利に作り替えました。名称もリニューアルし、sliceにplusのpが加わりました。
　　spliceは英語で「繋ぎ合わせる」という意味です。つまり、**ロープの一部を切り取って、残った部分を繋ぎ合わせたい時**や**ロープに金具など追加したいitemがある時**に使います。**まずは切り取る起点(start)**を指定します。そこからいらない部分を**起点から何個目までか(deleteCount)**を指定します。最後に金具を取り付けるために**追加したいitem**を指定します。
　　spliceの新機能により、ロープを狩猟のための仕掛けなどの全く新しい道具に変換することができるようになりました。ただし、材料は使い切ってしまうので、**元のロープに戻すことはできません。**

- **返値: 取り除かれた要素を含む配列**
- **元の配列: 取り除かれた要素を含まない配列**


　　
[参考: spliceMDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)


## まとめ
- **slice** : 元の配列や文字列から、必要な箇所（インデックス番号がstartから(end - 1)までの要素)を取り出すメソッド。返り値は、取り出された新しい配列で、元の配列は変わらない。

- **splice** : 元の配列や文字列から、不要部分を取り除いたり、新しい要素を繋ぎ合わせるメソッド。返り値は、取り除かれた要素を含む配列。元の配列は、取り除かれた要素を含まず、新しい要素が加わった配列。
  　　　　削除・・・インデックス番号 start から deleteCount 個目までの要素
　　　　追加 ・・・ インデックス番号 start の位置


　　　最後まで読んでくださって、ありがとうございました。
GitHub Actionsでダウンロードに失敗するときには HTTP HEADER に GitHub TokenでBearer認証をかける

GitHub Actionsで，たとえばEXLAのように大きなファイルをダウンロードするような
Hexライブラリを利用する場合に，GitHub ActionsによるCIでダウンロードに
失敗することがあります．本記事は，そのような場合に有効な方法を示します．
[Jonatan Kłosko](https://github.com/jonatanklosko) さんが教えてくれました．

## 方法 (EXLAの場合)

次のようにして，環境変数 `XLA_HTTP_HEADERS` に GitHub Token で Bearer 認証をかけます．

```yaml
env:
  XLA_HTTP_HEADERS: "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"
```

## 一般解

HTTPでダウンロードするときに，HTTP HEADERに `Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}` を渡します．

## 適用例

https://github.com/zeam-vm/pelemay_backend/pull/232
Chef有償化とは、”具体的に” 何を意味するのか？

https://www.creationline.com/tech-blog/30958

上記記事で説明されている通り、今まで完全に無料で使えていたChefは、Chef v15以降はProgress社からライセンスを取得しなくてはいけなくなりました。

このChefの有償化について、**具体的にどういうこと**なのか。何が変わったのか。

今まで無料でChefを利用してきた**企業が考慮すべき事柄**についてまとめます。

## なぜ"今"、Chefライセンスについて考えるのか？

2019年にChefは有償化されました。4年も前のことになります。

企業によっては、今まで通り無料でChefを使い続けているかもしれません。そこにはなんの問題もありません。なぜならChef v14までは従来通りライセンスを取得せずに無償で使い続ける事ができるからです。

しかし、LinuxやWindowsなどのサーバーOSのバージョンが上がるにつれて、**互換性の問題**でChef v14が動作しなくなる環境がでてきます。自然な流れとしてChefのバージョンもv15+に上げていく必要があります。遅かれ早かれChefを使うすべての企業がいずれはChef v15+を使うようになります。

この時に、真剣に考慮すべきライセンスの問題が発生します。

---

Chef v14の時と同じ感覚で、Chef v15を使ってしまうと、**ライセンス違反**を犯してしまうことになるのです。

_ーーどういうことでしょうか。_

故意にライセンス違反を犯す、ということではなく、社内のインフラエンジニアが何も気にせずに、今まで通りにChefを使い続けてしまう危険性があります。Chef v14 までは何の問題もありませんでした。無料で使う事ができていたからです。しかしChef v15以降を使う場合、**事前に**Progress 社からライセンスを取得する必要があります。Chefのバージョンを気にせずにChefを利用し続けている企業は、**重大なリスク**がそこに潜んでいることを認識しておく必要があります。

_ーー「リスクが潜んでいる」、とは？_

Chefのライセンス販売を行っているのは米国のProgress社です。米国の企業であり、ライセンス規約違反に対して強いアクションを取る可能性があります。**訴訟問題に発展するリスク**があります。

_ーーリスクが放置されているのは、なぜか。_

一つには、**無断でChefを使い続けることが技術的に可能**であることが挙げられます。つまり、ライセンスの取得をせずにChefを利用し続けてしまい、組織ぐるみで**知らぬ間にライセンス規約違反**を犯してしまう可能性があるのです。

そのためにChefのライセンスについて正しく理解する必要があるのです。

## 無断で使い続けることができてしまうのか？

できてしまいます。

十分に理解するために、有償化がどのようにして行われているかを知る必要があります。

次のようなターミナル出力をご覧になった事があるでしょうか。
Chef v14では出力されず、Chef v15以降から出力されるようになったものです。初回実行時だけ出力されるものです。

```
mask@MBP:~$ chef install                                            
+---------------------------------------------+
            Chef License Acceptance

Before you can continue, 3 product licenses
must be accepted. View the license at
https://www.chef.io/end-user-license-agreement/

Licenses that need accepting:
  * Chef Workstation
  * Chef Infra Client
  * Chef InSpec

Do you accept the 3 product licenses (yes/no)?
```

現場で働くインフラエンジニアの方々は、見たことがある、とお答えになると思います。
この出力に'yes'と入力することでChef v15+を使うことができるようになります。
それは以下の Agreement に同意したことを意味します。

https://www.chef.io/end-user-license-agreement/

この Agreement には次の文言が含まれています。

>"IF...YOU INTEND TO USE THE PRODUCT FOR COMMERCIAL PURPOSES, YOU MUST CONTACT PROGRESS DIRECTLY TO OBTAIN A COMMERCIAL LICENSE FOR THE PRODUCT."

つまり、商用目的でChefを利用する場合、Progress社から商用ライセンスの購入を義務付けており、そうした上でChefを使うことに同意することをすべてのChef利用者に課しています。

既に会社としてライセンスを取得済であれば問題にはなりません。
しかし、万が一、エンジニアが勝手に Agreement に同意していることを会社が把握しておらず、ライセンスを取得していない状態でChefを使い続けてしまうなら、無断でソフトウェアを利用していることになり、**組織ぐるみのライセンス規約違反**を犯してしまうことになってしまうのです。

さらに深刻なこととして、当該Agreementは一度、'yes'と入力してしまうと便宜上2度と出力される事がないために、ライセンス違反に企業が気づくことすらない、ないしは発見が遅れてしまう危険性もあるのです。

## どの機能が無料で使えなくなるのか？

基本的に**すべてのChef機能**が有償になります。
レシピやCookbookをローカルで実行するChef SoloやChef Workstationの利用を含むすべてのChef機能においてライセンスの取得が必要になります。

OpsWorksやState Manager などのAWSが提供するChef関連サービスにおいてもライセンスの取得が必要になります。

## ライセンスに関して問い合わせる

社内で利用されているChefのバージョンを把握しChefライセンスについて**国内代理店に問い合わせる事**ができます。

現状、Chefの技術サポート・コンサルやライセンス販売を国内で行っているのは、以下の1社のみのようです。

__ライセンスや技術サポートについて詳しくは、連絡先： support@chef-sec.com にお問い合わせください。__ 

www.chef-sec.com
GitHub Actionsで複数行の文字列をstep間で受け渡す


## はじめに
GitHub Actions使ってますか？私はめっちゃ使ってます。
ずっとstep間での **複数行の文字列の受け渡し方法** に悩んでいたのですが、オフィシャルドキュメントをゆっくり読んでいたら、めちゃくちゃ普通に書いてあることに気が付きました。

- https://docs.github.com/ja/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
- https://docs.github.com/ja/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter

> 複数行の文字列の場合、次の構文で区切り文字を使用できます。

```text
{name}<<{delimiter}
{value}
{delimiter}
```

えぇぇ、この記述って昔からあったっけ？
なんで俺は気が付かなかったんだ・・・
なんで俺は改行文字をエスケープしたりファイルを媒介したりする苦労をしていたんだ・・・

正確な情報は常に公式ドキュメントにありますが、また忘れる可能性が高いので、自分のための備忘としてQiitaに記録しておこうと思ってこの記事を書いてます。

※　この記事は2023/08/21現在の情報に基づいて書いています。

## 複数行の文字列の受け渡しの実装例

公式ドキュメントでは環境変数( `$GITHUB_ENV` )を利用した受け渡しの例が書いてあります。
そして、公式ドキュメントに記載がありますが、同様に`$GITHUB_OUTPUT` を利用して受け渡しすることも可能です。
その例を以下にSnippetとして書いておきます。

この例では、Slack通知を行うActionに対して、事前のstepで処理したレポートファイルの中身を渡しています。デリミタの乱数化は公式ドキュメントの例に従ってます。

```yaml
jobs:
  check-xxxxx:
    name: Check xxxxx
    runs-on: ubuntu-latest

    defaults:
      run:
        shell: bash
        working-directory: code/xxxxx-check

    env:
      REPORT_FILE: "/tmp/report-${{ github.run_id }}.txt"

　　　　　　　　　　　　- name: "前処理をしてREPORT_FILEに出力しましょう"

      - name: Check report file
        id: check-report-file
        run: |
          if [ -s ${{ env.REPORT_FILE }} ]; then
            EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
            echo "report<<$EOF" >> "$GITHUB_OUTPUT"
            cat ${{ env.REPORT_FILE }} | tee -a "$GITHUB_OUTPUT"
　　　　　　　　　　　　　　　　　　　　　　　　cat ${{ env.REPORT_FILE }} >> "$GITHUB_STEP_SUMMARY"　# Workflowの概要ページに出力したい場合の処理
            echo "$EOF" >> "$GITHUB_OUTPUT"
          fi
          exit 0

      - name: Notificate to Slack
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_CHANNEL: "xxxxx"
          SLACK_USERNAME: GitHub Actions
          SLACK_ICON_EMOJI: ":xxxxx:"
          SLACK_COLOR: "#FF0000"
          SLACK_TITLE: "xxxxxx"
          SLACK_MESSAGE: "レポートは以下。\n```${{ steps.check-report-file.outputs.report }}```"
```

## まとめ

公式ドキュメントをちゃんと読もう。

### 追記(2023/08/21 22:23)

もしかして `set-output` がdeprecatedになって `$GITHUB_OUTPUT` を使うようになったときに、この書式が増えたのかな。なるほどなー

- そのことを話しているっぽい発言: https://github.com/orgs/community/discussions/26288#discussioncomment-3876281
truncate - ファイルの切り詰めと拡張･･･を dd コマンドでやる方法

## はじめに

ちょっとした小ネタです。`truncate` コマンドはファイルの中身を残したまま、任意のファイルサイズまで切り詰めたり、または任意のファイルサイズまで拡張するコマンドです。正直言って使ったことはありません。使う場面は……仮想ディスクのイメージのサイズを変更したり？でもその場合は専用のコマンドを使うでしょうし、使う場面もあまり思いつきません。それでも `truncate` コマンドというものが用意されているということは必要とする人もいるのでしょう。

さてこの `truncate` コマンドですが POSIX コマンドではありません。Linux や FreeBSD には入っているようですが、macOS やその他の BSD には入っていないようです。この記事はこの `truncate` コマンド相当のことを POSIX コマンドだけでやるにはどうするかという話です。

## dd コマンドを使う

タイトルでネタバレしていますが、答えは `dd` コマンドを使います。まず説明用にファイルを作成します。

```console
$ printf '0123456789' > file.txt # 検証用に10バイトのファイルを作成

$ od -tx1 file.txt # 中身の確認
0000000 30 31 32 33 34 35 36 37 38 39
0000012
```

### ファイルの切り詰め

ファイルの中身はそのままに 5 バイトまで減らします。

```console
$ dd if=/dev/null of=file.txt obs=5 seek=1
0+0 records in
0+0 records out
0 bytes copied, 7.7843e-05 s, 0.0 kB/s

$ od -tx1 file.txt
0000000 30 31 32 33 34
0000005
```

### ファイルの拡張

ファイルの中身はそのままに 10 バイトまで拡張します。

```console
$ dd if=/dev/null of=file.txt obs=10 seek=1
0+0 records in
0+0 records out
0 bytes copied, 7.7843e-05 s, 0.0 kB/s

$ od -tx1 file.txt # 拡張した部分には NULL 文字が入る
0000000 30 31 32 33 34 00 00 00 00 00
0000012
```

## 解説

以下の例を元に解説します。

```console
$ dd if=/dev/null of=file.txt obs=10 seek=1
```

`obs` は書き込みのブロックサイズを 10 バイトに設定しています。そして `seek` は書き込み時に移動するブロック数で 1 ブロック、つまり 10 バイトを移動してから書き込むという意味です。もし `seek` が 2 なら 10 × 2 で 20 バイトです。書き込む内容は `/dev/null` であるため何も書き込みません。もしここに中身のあるファイルを指定した場合は、そのファイルの内容が書き込まれます。

`obs` と `seek` を逆にして以下のようにしても同じよう動きますが、ブロック単位で処理することを考えると `obs` でサイズを指定したほうが効率が良いと思います（未検証）

```console
$ dd if=/dev/null of=file.txt obs=1 seek=10
```

### おまけ サイズ指定について

**POSIX で標準化されている** `obs` のサイズ指定には `b` と `k` の単位を指定できます。`b` は 512 バイト、`k` は 1024 バイトです。 POSIX で標準化されていない拡張機能ですが、おそらく `M` や `G` も使用可能です。

```console
$ dd if=/dev/null of=file.txt obs=1b seek=1
0+0 records in
0+0 records out
0 bytes copied, 9.0135e-05 s, 0.0 kB/s

$ ls -al file.txt
-rw-rw-r-- 1 koichi koichi 512 Aug 21 20:07 file.txt

$ dd if=/dev/null of=file.txt obs=1k seek=1
0+0 records in
0+0 records out
0 bytes copied, 7.8725e-05 s, 0.0 kB/s

$ ls -al file.txt
-rw-rw-r-- 1 koichi koichi 1024 Aug 21 20:08 file.txt
```

そしてこちらも **POSIX で標準化されている書き方**ですが掛け算も使えます。

```console
$ dd if=/dev/null of=file.txt obs=10x1k seek=1
0+0 records in
0+0 records out
0 bytes copied, 9.0135e-05 s, 0.0 kB/s

$ ls -al file.txt
-rw-rw-r-- 1 koichi koichi 10240 Aug 21 20:12 file.txt
```

このような書き方ができますが、あまり使うことはないでしょう。使うとしたら例えば `10M` の代わりに POSIX に準拠したわかりやすい（？）書き方として `10x1kx1k`と書く時ぐらいでしょうか。はいそうです。複数の値の掛け算ができますす。ちなみにこのような書き方ができるのは `bs`、`cbs`、`ibs`、`obs` のみです。

## さいごに

以上です。
Netlifyでのプリレンダリング: なぜ重要なのかとその設定方法

シングルページアプリケーション (SPA) が日常的に使用されるようになる中、そのSEO対策は非常に重要となってきました。特に、ログイン機能を持たない公開サイトでSPAを採用している場合、検索エンジンのクローラがコンテンツを正しく解釈するためのプリレンダリングは欠かせません。この記事では、Netlifyでのプリレンダリングの重要性と設定方法について詳しく解説します。

# プリレンダリングとは？

プリレンダリングは、クローラがSPAのコンテンツを正しく解釈できるように、サーバーサイドでページの静的なスナップショットを生成する技術です。これにより、クローラはJavaScriptを実行せずにページのコンテンツを読み取ることができます。

# なぜNetlifyでのプリレンダリングが重要なのか？

GoogleやBingなどの主要な検索エンジンは、GoogleのAjax Crawlingの標準をサポートしています。この標準に従い、クローラはSPAを検出すると、リクエストに特定のクエリパラメータを送信します。これに応答して、サーバはユーザがSPAを実行したときに実際に表示されるコンテンツを表すドキュメントを返すことができます。

# Netlifyでのプリレンダリングの設定方法

1. Netlifyのダッシュボードにログインします。
2. 対象のサイトを選択します。
3. 「Site configuration」をクリックします。

4. 「Build & deploy」を選択します。
5. 「Post processing」セクションに移動し、「Prerendering」を有効にします。

    「Configure」ボタンをクリックすると設定項目が表示されます。
    ![FireShot Capture 211 - Build & deploy - Site configuration - kotonoba - Netlify - app.netlify.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20464/31ab75b4-b957-3a5e-12dd-74141d24329d.png)
    Enable prerendering with Netlifyにチェックを入れるとプリレンダリングが始まります。
    ![FireShot Capture 212 - Build & deploy - Site configuration - kotonoba - Netlify - app.netlify.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20464/33d2397d-29b6-a65f-8710-e37dc6cc4fbc.png)



以上で、Netlifyの組み込みのプリレンダリングが設定されます。この機能を有効にすると、Netlifyはプリレンダリングされたページを24〜48時間キャッシュします。

# まとめ

Netlifyでのプリレンダリングは、シングルページアプリケーションのSEOを強化するための強力なツールです。設定は簡単で、数ステップで完了します。SPAを使用している場合、Netlifyのプリレンダリングを活用して、サイトの検索エンジンのランキングを向上させることをおすすめします。

https://docs.netlify.com/site-deploys/post-processing/prerendering/#set-up-prerendering
Trello API KeyとTokenの取得

# はじめに
Trelloをプログラムを使い操作するため、Trelloに用意されたAPIを使用します
この文書はAPIを使用するためのAPI keyとTokenを取得します

# 環境
- この文書はTrello 無料アカウントを使用し作成しています
- API keyとTokenは掲載画像取得のために作成しており、すでにこれらのKeyは削除済みです

# 主な手順
1. Trelloアカウントへログインした状態で、Power-Upページへアクセスします
2. Power-Upを新規作成し、APIキーとTokenを取得します

# 1. Power-Upページへアクセス
Trelloへログインした状態でPower-Upページへアクセスします
https://trello.com/power-ups/admin

https://trello.com/power-ups/admin


プライバシーとコンプライアンス
1. Trello開発者契約を読み、チェックを入れます
2. 「続行」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/54c46140-5dd7-fdcf-68c7-cbd015855b9b.png)



Power-Up & 統合
3. 「新規」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/9e77eb9b-2f65-dbf4-85e5-fc352fe1a56b.png)


Power-Upまたは統合を新規作成
4. 任意の名前を入力します（例：Trello my key)
5. Trelloワークスペース を選択します
6. 空白(入力不要です)
7. メールアドレスを入力します
8. メールアドレスを入力します
9. 作者名を入力します
10. 「作成」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/7d441ed3-67be-31d1-3c2d-4cc831d0656b.png)


# 2. APIキーおよびTokenの作成
APIキー
11. 左側メニューから「APIキー」をクリックします
12. 「新しいAPIキーを生成」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/5617276a-3b87-2498-b8ca-86ed186f9c31.png)


APIキーを生成
13. 「APIキーを生成」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/7dc1f73a-fc69-ff03-03c5-dfb1f170ffc0.png)


APIキー
14. 表示されたAPIキーをメモします（後からでも確認可能です）
15. Token発行のために「トークン」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/960a335a-45f4-2167-d6d4-3792dd492db4.png)

アクセス許可処理
16. 「許可」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/affa5249-ea0e-6679-e6d0-b627122e5df9.png)

トークンの発行
17. 表示されたTokenをメモします（後からでも確認可能です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/6c454eed-f5fa-b850-dd04-2e3a8c60bfb1.png)

画面を閉じると、処理は完了です。

# 参考
Trello API ドキュメント
https://developer.atlassian.com/cloud/trello/

The Trello REST API
https://developer.atlassian.com/cloud/trello/rest/
Cloudflare Magic WAN ヘルスチェックが全然上がらないとき

## 概要

クラウド環境で、Magic WAN のトンネルヘルスチェックの折返しが帰ってこず、ヘルスチェックがダウン判定になることがありました。
[こちらのケース](https://qiita.com/khayama/items/20a0b49458a2296f92dc#%E3%83%88%E3%83%B3%E3%83%8D%E3%83%AB%E3%83%98%E3%83%AB%E3%82%B9%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%81%AE%E6%A7%8B%E6%88%90)もありますが、今回はちょっと違って CPE 発の「いきなり ICMP Echo Reply」を、クラウド出口のファイアウォールが通してくれなさそうです。

二番目の矢印を誰かがポリシーで落としてる。

```mermaid
sequenceDiagram
    participant Cloudflare_各DC
    participant CPE

note left of Cloudflare_各DC: Health check 開始
note left of Cloudflare_各DC: 送信元:CPE、宛先:オレ
note left of Cloudflare_各DC: ICMP Echo Reply
    rect rgb(191, 223, 255)
note right of Cloudflare_各DC: IPsec Tunnel から送信
    Cloudflare_各DC->>+CPE: 
    end
    note right of CPE: 単にルーティング<br>（折り返すだけ）
    note left of CPE: 物理インタフェースから送信<br>（転送表による）
    CPE->>- Cloudflare_各DC: 
note left of Cloudflare_各DC: OK
```
CPE は顧客側の IPsec 終端装置


### ヘルスチェックのパケット
|From|To|Type|モニターが期待する動作|
|-|-|-|-|
|CPEのIP|Cloudflare_各DCの自分IP|ICMP Echo Reply|折返えされて自分に戻ってくる|

## 課題

場合によっては、折返しのパケットが途中のルータのポリシーで破棄されることがあります。
そのあたりのポリシーをユーザではなんともできないことがあります。

## 対策
- ヘルスチェックへの折返しも[トンネルを通す](https://developers.cloudflare.com/magic-wan/how-to/run-tunnel-health-checks/)ようにする
    - ヘルスチェックの送信元は CPE のIP ではなく、Cloudflare 指定の `172.64.240.252/30` から選ぶ
    - CPE では「送信元が `172.64.240.252/30` の場合、トンネルインターフェースに転送」と書く
- そもそも、Cloudflare の 各IP をトンネルインターフェースにルーティングできれば良さげですが、IP 公開もないので、この対応

### ヘルスチェックのパケット
|From|To|Type|モニターが期待する動作|
|-|-|-|-|
|172.64.240.253 or 254|Cloudflare_各DCの自分IP|ICMP Echo Reply|折返えされて自分に戻ってくる|

```mermaid
sequenceDiagram
    participant Cloudflare_各DC
    participant CPE

note left of Cloudflare_各DC: Health check 開始
note left of Cloudflare_各DC: 送信元:172.64.240.252/30、宛先:オレ
note left of Cloudflare_各DC: ICMP Echo Reply
    rect rgb(191, 223, 255)
note right of Cloudflare_各DC: IPsec Tunnel から送信
    Cloudflare_各DC->>+CPE: 
    note right of CPE: 送信元IPを参照し<br>ルーティング<br>（PBR）
    note left of CPE: IPsec Tunnelから送信
    CPE->>- Cloudflare_各DC: 
    end
note left of Cloudflare_各DC: OK
```

折返しもトンネル（vti1）を通り、経路中で破棄されることがなくなりました。

### 設定の一例
```
sudo ip route flush table 1000
sudo ip rule add from 172.64.240.252/30 table 1000 prio 100
sudo ip route add default dev vti1 table 1000
```
キャプチャ（トンネルインタフェースに折返し、TTLが一つ減る）
```
Capturing on 'vti1'
    1 0.000000000 172.64.240.254 → <CF_IP> ICMP 84 Echo (ping) reply    id=0x0b63, seq=0/0, ttl=64
    2 0.000051618 172.64.240.254 → <CF_IP> ICMP 84 Echo (ping) reply    id=0x0b63, seq=0/0, ttl=63
```

## その他の方法
他にヘルスチェックの折返しをトンネルに流す方はいくつかありそうですが、柔軟さでは上記が良さげです。


その他だと
- トンネルが上がったら、デフォルトルートをトンネル側に優先度の高めで切って、トンネルから除外したいもの（デバイスへのSSHとか）は個別にスタティックで物理に放る、というスクリプト
- 受信したICMPパケットは転送表を無視して、受信したインタフェースに折り返す、という機能

あたりでしょうか。

一方、折返しをトンネルに流さず、ヘルスチェックのタイプを ICMP Echo にするというのもありますが、この場合は中間のファイアウォールなどでセッションなどが作られ、無駄に Echo Reply を待つ、というような弊害も考えられます。


## 本家の解説
https://developers.cloudflare.com/magic-wan/how-to/run-tunnel-health-checks/
docker-composeを使用したmetabeseの構築

# 概要
 `metabese`を使用する機会があったので、その構築手順を備忘録も含めて記載します。

# `metabase`の概要
- `metabase` とは、OSS（オープンソースソフトウェア）のデータ可視化ツール
- 下記は公式の`git hub`

https://github.com/metabase/metabase

# 構築手順
ディレクトリ構成と各ファイルの内容を記載する

## 1. ディレクトリー構成
```sh
.
├── conf/
│   ├── metabase/
│   │   ├── matabase-data　 #← 自動生成
│   │   └── .env
│   └── postgresql/
│       ├── db_voume # 　← 自動生成
│       └── .env
├── .gitignore
└── dockercompose.yml     
```
# 2. 各ファイルの設定内容
ディレクトリー構成に従って、各ファイルを作成する
## docker-compose.yml
```docker-compose.yml
version: "3.9"
services:
  metabase:
    image: metabase/metabase:latest
    container_name: metabase
    env_file: ./conf/metabase/.env
    volumes:
      - ./conf/metabase/metabase-data:/metabase-data
    ports:
      - 3000:3000
    tty: true
    healthcheck:
      test: curl --fail -I http://localhost3000/api/health || exit 1
      interval: 15s
      timeout: 5s
      retries: 5
    depends_on:
      - db
  db:
    image: postgres:latest
    container_name: postgresql
    env_file: ./conf/postgresql/.env
    volumes:
      - ./conf/postgresql/db_volume:/var/lib/postgresql/data
    ports:
      - 5432:5432
    restart: always
volumes:
  db_volume: {}
```
# .envファイル
- `USER`、`PASS`、`DB`は、任意で変更しても可能
```sh
metabaseの.envファイル
# MB_DB_FILEは下記の書き方で固定
MB_DB_FILE=/metabase-data/metabase.db
MB_DB_TYPE=postgres
MB_DB_DBNAME=test
MB_DB_PORT=5432
MB_DB_USER=postgres
MB_DB_PASS=Test1234
MB_DB_HOST=db # docker-compose.ymlに記載したservices名と合わせる
```

```sh
# postgresの.envファイル
POSTGRES_DB=test
POSTGRES_USER=postgres
POSTGRES_PASSWORD=Test1234
```

# コマンド
今回の構成は、`Dockerfile`がないので、`build`コマンドは不要
```sh
docker compose up -d
```

必要に応じてログを確認する
```sh
docker compose logs -f
```

# metabaseが立ち上がった後の設定
入力項目がある為、下記の手順に沿って入力する
## 設定項目1
- 任意の値を入力する
![設定1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664659/b8fb41a0-3554-6fa5-7fdf-32474bddb341.png)

## 設定項目2
- `metabase`の`.env`ファイルに記載した内容を入力する
![設定2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664659/54a940ca-ddc3-d445-9fa4-76d78a8d84db.png)

## 設定項目3
- フィニッシュを押下する
![設定項目3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664659/e6615c1b-b66f-51ad-de9d-77999a8b15e2.png)


# 参照
- [[公式] Running Metabase on Docker](https://www.metabase.com/docs/latest/installation-and-operation/running-metabase-on-docker)
- [[ データ可視化ツール]MetabaseをDocker上で構築してRedshiftへ接続する](https://dev.classmethod.jp/articles/metabase_ond_cors/)
- [OSSのデータ可視化ツール「Metabase」が超使いやすい](https://qiita.com/acro5piano/items/0920550d297651b04387)
[Vue.js] v-showとv-ifの違い

# 目的
v-ifもv-showも式の結果によって要素の表示・非表示を切り替えられるディレクティブのなので、その使い分けの方法の調査

# v-if
式の結果によってDOM要素を追加、削除する
```例
<p v-if="引数">
	// 真なら表示、偽なら非表示
<p>
```

# v-show
式の結果によってDOM要素のdisplayプロパティを変更する
```
<p v-show="引数">
	// 真なら表示、偽なら非表示
</p>
```

# 使い分け
#### 頻繁に切り替えを行う時はv-showを使う
理由
スタイルの操作よりDOM操作の方がレンダリングのコストが高いから
  
 
  
#### 式の評価結果がほとんど変わらない時はv-ifを使う
理由
初期表示時にレンダリングが必要ない時にはDOM要素を生成せずにコストを抑えたいから
【Xcode】シュミレーターが起動できなくなった

# はじめに
突然シュミレーターが起動できなくなったので解決方法を記録しておきます

# エラー
```
Use the device manager in Xcode or the simctl command line tool to either delete the device properly or erase contents and settings.
```

![スクリーンショット 2023-08-21 19.55.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/16ec5c01-3c1d-79da-45da-b52d1bbd3d77.png)

# 原因
不明

# 解決方法
```:ターミナル
killall "Simulator" 2> /dev/null; xcrun simctl erase all
```

# 参考記事
https://stackoverflow.com/questions/5125243/how-can-i-reset-the-ios-simulator-from-the-command-line
HTML基礎①

# 練習
本日はテーブルタグについて勉強しました。
使用ソフト：eclipse

## 例1

~~~~html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>table tag1</title>
</head>

<body>
<table border = "1">
<tr>
 <th>生徒名</th><th>学籍番号</th> 
</tr>
<tr>
 <th>山田太郎</th><th>1001</th>
</tr>
<tr>
 <th>田中花子</th><th>1002</th> 
</tr>
</table>
</body>
</html>
~~~~~

### 例2

~~~~html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>table tag2</title>
</head>

<body>
<table border = "2">
<tr>
 <th>生徒名</th><th>学籍番号</th><th>学年</th>
</tr>
<tr>
 <th>山田太郎</th><th>1001</th><th>1年</th>
</tr>
<tr>
 <th>田中花子</th><th>1002</th><th>2年</th>
</tr>
</table>
</body>
</html>
~~~~~

本日の気付き：htmlでテーブルタグを使えばグラフのようなものができる。
本日の学び：<table border = "n">の数字を変えることで枠の数を増やすことが可能
JAVA応用④

# 課題
問題：標準入力からファイルのパスを入力し最後を表示するプログラムを作成せよ
使用ツール：eclipse

~~~~java
package ad;

import java.util.Scanner;

public class adr{

	public static void main(String[] args) {
		System.out.println("ファイルパス");
		String str=extracted().next();

		String[] values= str.split("/");
		String lastOne = values[values.length-1];
				System.out.println("「"+lastOne+"」");
			}

	private static Scanner extracted() {
		return new Scanner(System.in);
	}
					
		}

~~~

## aaa/bbb/cccと入力し他場合の結果
~~~~
ccc
~~~~

本日の気付き：　lengthを使用することで文字だけでなく("/")区切った部分も表示できる。
本日の学び：先日のを含めるとパターンによりvalues[n]、values.lengthと使い分けが可能。
JAVA応用③

# 課題
問題:　電話番号を入力したら市外局番のみを返すプログラムを作成せよ
使用ツール:　eclipse

## 回答

~~~~java
package tel;

import java.util.Scanner;

public class N0 {

	public static void main(String[] args) {
		
		System.out.println("番号入力");
		Scanner s=new Scanner(System.in);
		String str=s.next();
        String[]values=str.split("-");
			System.out.println("市外局番は"+values[0]);
		}
				
	}

~~~~

01-2345-6789と入力した場合の結果

~~~~~~~
番号入力
01-2345-6789
市外局番は01
~~~~~~~

本日の学び:splitを利用することで("")内の文字を利用して区切れます。
この場合だと01("-")2345("-")6789といった形になります。

本日の気付き:今回の場合values[0]（JAVAは0から始まるため）を指定していますが、[]の中身の数字を変えると以下のように変わります。


### values[1]の場合


~~~~java
package tel;

import java.util.Scanner;

public class N1 {

	public static void main(String[] args) {
		
		System.out.println("番号入力");
		Scanner s=new Scanner(System.in);
		String str=s.next();
        String[]values=str.split("-");
			System.out.println(values[1]);
		}
				
	}

~~~~

01-2345-6789と入力した場合の結果

~~~~~~~
番号入力
01-2345-6789
2345
~~~~~~~

#### values[2]の場合

~~~~java
package tel;

import java.util.Scanner;

public class N2 {

	public static void main(String[] args) {
		
		System.out.println("番号入力");
		Scanner s=new Scanner(System.in);
		String str=s.next();
        String[]values=str.split("-");
			System.out.println(values[2]);
		}
				
	}

~~~~

01-2345-6789と入力した場合の結果

~~~~~~~
番号入力
01-2345-6789
6789
~~~~~~~

上記のような形で変わります、中身はこのようなイメージなのかもしれません。[0]("-")[1]("-")[2]。
SESで「入力パラメータに無効な値または範囲外の値が指定されました。Identity is not verified」というエラーが出た件について

Simple Email Service(SES)でメールの受信においてルールセットにルールを作成する際に以下のように「送信者への返信」を設定しようとしました。

![スクリーンショット 2023-08-21 193116.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/6e06a306-7a35-5243-49fa-c49314804bd6.jpeg)
Terraformでは、以下のsenderの部分です。
```
bounce_action {
・
・
・
    sender          = "sample@sample.com"
・
・
・
}
```
しかし、「入力パラメータに無効な値または範囲外の値が指定されました。Identity is not verified: ・・・・」というエラーに遭遇しました。(Terraformでは、「Error creating SES rule: InvalidParameterValue: Identity is not verified: ・・・・」というエラーが出ます。)

今回はその解決法を紹介します。

# 解決方法
「us-east-1」regionで「検証済みのID」にて「IDの作成」でIDを作成します。そして、作成したID内で表示されているDomainKeys Identified Mail (DKIM)のCNMAEをRoute53に登録します。そうすると、作成したIDの「ステータス」が「検証済み」となります。これにより「送信者への返信」の設定が可能となります。

![スクリーンショット 2023-08-21 194037.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/34cacb0e-7c7e-dd2c-1e13-29282fdb0503.jpeg)

region毎に検証済みのドメインを作る必要があるようです。

# 補足：Route53での登録方法
ここではCNMAEの登録方法を説明します。Route53でドメインを取得している前提とします。
以下のとおりホストゾーンを選択します。
![host_zone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/37fc3991-c6f7-e508-0c10-3ed03bfc63c9.png)
そして、CNAMEを登録したいホストゾーン名を選択します。
![スクリーンショット 2023-09-10 163322.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/15da8816-aa19-b69c-5625-375719e90656.png)
次に、「レコードを作成」を選択します。
![スクリーンショット 2023-09-10 163539.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/7d5f4499-c108-db71-598c-5ef0b0e2924a.png)
次に、「シンプルルーティング」を選択して「次に」を選択します。
![FireShot Capture 004 - share-law.com - レコードを追加 - us-east-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/bc2f0a76-5fb1-387c-cb6d-75edf1699220.png)
上述した「DomainKeys Identified Mail (DKIM)のCNMAE」３つを入力していきます。「レコード名」の項目は「DomainKeys Identified Mail (DKIM)のCNMAE」の「名前」のドメイン名の直前までをコピペします。
「値/トラフィックのルーティング先」の項目は「DomainKeys Identified Mail (DKIM)のCNMAE」の「値」をコピペします。そして、「シンプルなレコードを定義」をクリックします。これで一つ目のCNAMEの登録が完了です。これをあと２回繰り返して「DomainKeys Identified Mail (DKIM)のCNMAE」を合計３つ登録します。
![スクリーンショット 2023-09-10 164417.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/8cdaa5fd-a5c8-3172-aa43-9734b7650490.png)

Terraformだと例えば以下のようになります。

```
resource "aws_route53_zone" "zone" {
  name          = "sample.com"
  force_destroy = false
}

resource "aws_ses_domain_identity" "ses_us" {
  provider      = "us-east-1"
  domain = "sample.com"
}

resource "aws_ses_domain_dkim" "dkim" {
  domain = "sample.com"
}

resource "aws_route53_record" "dkim_record" {
  count   = 3
  zone_id = aws_route53_zone.zone.zone_id
  name    = "${element(aws_ses_domain_dkim.dkim.dkim_tokens, count.index)}._domainkey.${aws_route53_zone.zone.name}"
  type    = "CNAME"
  ttl     = "300"
  records = ["${element(aws_ses_domain_dkim.dkim.dkim_tokens, count.index)}.dkim.amazonses.com"]
}
```
以上でCNAMEの登録完了です。
Windowsでシリアル通信のCOMポート番号を確認する方法

### 王道は、

デバイスマネージャーを開いて確認する方法です。


https://qiita.com/kikuchiTakuya/items/5d4cef20998b99194d6a

<br /><br />コマンドで確認する方法が無いかググったところ、Qiitaから下記を見つけました。

https://qiita.com/cheer4u/items/9e78018ef339c2145cc3

<br /><br />他に、もっと簡単に確認できるコマンドを探したところ、下記を見つけました。

https://stackoverflow.com/questions/14990996/scan-com-port-batch-file

```dosbatch
mode | findstr "COM[0-9]*:"
```

シンプルですね。
ただ、これだと、以下の表示となります。

```dosbatch
デバイス状態 COM6:
```

（`mode`コマンドの出力結果から`COMx`を含む行を抜き出すだけのため）

`for`で項目を選択する方法も書いてありました。

```dosbatch
for /f "tokens=2" %%A in ('mode^|findstr "COM[0-9]*:"') do echo %%A
```

（コマンドプロンプトで直接実行する場合は`%%A`は`%A`にする）


原文は`"tokens=4"`になっていますが、日本語Windowsだと`2`です。

<br /><br />バッチファイル化する想定でしょうが、コマンドが長いので、
自分は、↓これを直打ちします。


```dosbatch
mode | find "COM"
```

COMポート番号を確認する目的としては、これで十分なので。
（なんなら、`mode`だけでもよい）


### <br />おまけ

`pyserial`を使った、pythonコードも見つけました。
Windows / Linux / MacOS に対応しています。

https://engineer-lifestyle-blog.com/code/python/serial-com-port-number-confirmation/ 

<hr>


### <br />おまけ＜その2＞

Macの場合は、`ls /dev/cu.*`です。

```sh
alias lsu='ls /dev/cu.*'
```
自分は**alias**定義して、`lsu`にしています。

:::note warn
`/dev/tty.*`ポートだと、マイコンへのアップロードでエラーが起きることがあるので、`/dev/cu.*`の方を使っています。
:::



以上です。
mvnwでJVMオプションを指定する方法

以下のようにMAVEN_OPTSを設定することで可能。
```
$ export MAVEN_OPTS=<JVN Option>
$ ./mvnw clean install
```
例えば、GCのログを取得したいなら以下のように指定（注：以下のGCログ取得の指定方法はJava9以降）
```
$ export MAVEN_OPTS="-Xlog:gc*:file=/path/to/your/logfile.log"
$ ./mvnw clean install
```
よく使っているバッチファイル

レベルは低いかもですが、自分がよく使っているバッチファイルです。

## 下位層のフォルダからファイルを回収する

``` sh
@ECHO OFF

FOR /R %%i IN (*.*) DO (
REM a. COPYする場合
COPY %%~fi %~dp0

REM b. 移動する場合
REM MOVE %%~fi %~dp0
)
```

> ### 別法
> 
> ``` sh
> FORFILES /S /M *.mp3 /C "CMD /C COPY @path ..\all"
> ```

## PNGをBase64に変換する

``` sh
@ECHO OFF

FOR /F %%I IN (.\input.txt) DO (
REM -F：強制的に上書きする
CERTUTIL -F -ENCODE  .\%%I %%~nI.txt
)
```

> - Base64の画像をHTMLに表示するには
> 
> ``` html
> <img src="data:image/png;base64,ここにBase64を貼り付け">
> ```
wifi6

## wifi6では
5Ghzを2つに分け、2.4Ghzと3つで使うことができる
### トライバンドができる
### クアッドバンド
https://www.infraexpert.com/study/wireless60.html
### 複数の周波数を用いることができる　
### だから複数のストリームを形成できる

### トライバンドのメリットは
接続する機器が増えると負荷が集中します。
※ちなみにデュアルバンド（2つの電波）
一方「トライバンド（3つの電波）」では、高速通信が可能な5GHz帯が2つに増え、2.4GHz帯と合わせて3つの電波を同時に利用できるので、
### 接続機器を分散させることができます。

https://www.iodata.jp/ssp/magazine/163/index.htm

## wifi 6E

Wi-Fi 6Eは、新たに解放された6GHz帯を利用できるWi-Fiの規格

https://businessnetwork.jp/article/9132/2/


## WPA3とは
WPA3の主な特徴は、SAEハンドシェイクによる防護、辞書攻撃・総当たり攻撃からの防護、192ビットの暗号化システム（CNSA）の実装などです。
## SAEとは
WPA3では、SAE (Simultaneous Authentication of Equals) ハンドシェイクという新たな手法が導入されています。SAEハンドシェイクは、前述のWPA2の脆弱性であるKRACKs（Key Reinstallation Attacks）を無効化するための技術です。

SAEハンドシェイクはパスワードのセキュリティを大幅に強化します。具体的には、攻撃者がパスワードを推測しようとして一定回数以上試行する（＝辞書攻撃や総当たり攻撃）と、その攻撃を自動的にブロックします。これにより、攻撃者による無数のパスワード試行を防ぐことができます。

https://www.netattest.com/wpa3-2023_mkt_tst#:~:text=WPA3%E3%81%AF%E3%80%81%E3%81%9D%E3%81%AE%E5%AE%89%E5%85%A8%E6%80%A7,%E3%81%93%E3%81%A8%E3%81%A7%E5%AE%9F%E7%8F%BE%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82


https://www.sms-datatech.co.jp/column/sec_wpa3/

## 無線LANの知識

### チャネルボンディング

https://milestone-of-se.nesuke.com/nw-basic/wireless/channel-bonding-and-mimo/

https://milestone-of-se.nesuke.com/nw-basic/wireless/wifi-summary/

## POEの知識
https://community.fs.com/jp/blog/what-is-power-over-ethernet-and-how-to-add-poe-in-network.html

https://community.fs.com/jp/article/poe-switch-types.html

## マルチギガビットイーサネットとは

https://www.infraexpert.com/study/ethernet14.html

## 無線で電波干渉を受けるチャネル

### W53とW56は外部レーダーを受けるグループ

### W53とW56は起動時1分間は無線LAN利用不可

### レーダーを受信したときも同様な動作

### このダイナミックにチャネルを変更する機能を「DFS(DynamicFrequencySelection)」といいます。

https://itbouzy.site/wifi/5ghz-radar/

https://internet.watch.impress.co.jp/docs/column/shimizu/1034357.html

## メッシュWi-Fiとは

https://www.buffalo.jp/topics/select/detail/meshwifi.html
OSってなに

# オペレーティングシステム（OS）
:::note
コンピューターやデバイスの基本的な機能や動作を制御するためのソフトウェアの集まり
:::

# OSの役割

### ファイルシステム管理
- データをファイルとして格納し、そのファイルを管理したり整理したりしている

### プロセス管理
- 複数のプログラムやタスクが同時に実行される際のスケジューリングや制御を行いリソースを管理している

### メモリ管理
- システムのメモリ（RAM）の割り当てと解放を管理している

### デバイスドライバ管理
- ハードウェアデバイスの操作を行うためのドライバを提供して、アプリケーションとデバイス間の通信を管理している

ハードウェアデバイスの例

・プリンター
・キーボード
・マウス

### ユーザーインターフェース
- ユーザーがデバイスやアプリケーションを操作するためのユーザーインターフェースを提供

コマンドラインインターフェース（CLI）やグラフィカルユーザーインターフェース（GUI）など

### セキュリティとアクセス制御
- システムのセキュリティを維持し、ユーザーやアプリケーションのアクセスを制御する

データの保護やユーザーの認証、権限管理などを行う
Docker Desktopインストール時、困りごと解決法（起動しない、docker-users）

# 概要
Docker desktopを以下の方法でインストールしたときに以下の2点で詰まったときの解決方法。発生事案としては多くないかもしないが、参考に。

https://docs.docker.com/desktop/install/windows-install/


# 環境
- Windows10 Home 22H2
- Dokcer Desktop 4.22.0

## 事象1: Docker Desktopは起動するがカーネルが古いと怒られる
起動したときに、以下のようなメッセージが表示される場合
```
Docker Desktop – WSL kernel version too low
```

### 対応
#### Step1: カーネルのバージョンを確認

:::note warn
PowerShellで以下のコマンドを打つ場合、必ず実行するユーザですること。つまり、管理者ユーザーでDocker Desktop起動して、本事象が発生したときには、管理者でPowerShellを起動する。ローカルユーザのままで以下のコマンドを打つと、ローカルユーザにおけるwslカーネルのバージョンが返ってくるため。
:::

```
PS C:\Users\user01> wsl --version
WSL バージョン: 1.2.5.0
カーネル バージョン: 5.15.90.1
WSLg バージョン: 1.0.51
MSRDC バージョン: 1.2.3770
Direct3D バージョン: 1.608.2-61064218
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.19045.3324
```

#### step2: カーネルのアップデートを実行
```
PS C:\Users\user01> wsl.exe --update
```

※以下の記事参照
https://learn.microsoft.com/ja-jp/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package

## 事象2: docker-usersに実行ユーザを追加したいが、windowsの設定に項目が見当たらない

以下のDokcer desktopのインストール手順（インストーラ経由）で実行していると、以下の手順の項目が見当たらないことがある。

>(手順.5) 管理者アカウントがユーザー アカウントと異なる場合は、そのユーザーをdocker-usersグループに追加する必要が>あります。管理者としてコンピューターの管理を実行し、[ローカル ユーザーとグループ] > [グループ] > [docker-users]に移動します。右クリックしてユーザーをグループに追加します。変更を有効にするには、サインアウトしてから再度サインインします。

https://docs.docker.com/desktop/install/windows-install/


:::note warn
インストールしたDocker Desktopをクリックしても、そもそも起動しない場合、この設定がうまくいっていない可能性もあるため、確認したい。
:::


### 対応

:::note warn
Windows Homeエディションなどでは、上記の設定項目が存在しないため、GUIからは設定ができない。
:::

#### Step1: 追加するユーザ名を確認
PowerShellかコマンドプロンプトで以下のコマンドでwindows内のユーザ名一覧を表示して、docker-usersに追加したいユーザ名を確認
```
PS C:\Users\user01> net user

\\My PC のユーザー アカウント

-------------------------------------------------------------------------------
Administrator            Admin            DefaultAccount
Guest                    xxxxxxx1         xxxxxxxx2
user01                   user02           
コマンドは正常に終了しました。

```

#### Step2: グループdocker-usersにユーザを追加
```
PS C:\Users\user01> net localgroup docker-users <user> /add
```

#### Step3: 追加されたか確認
```
PS C:\Users\user01> net user user01
ユーザー名                           user01
フル ネーム                          user01
コメント
ユーザーのコメント
国/地域番号                          000 (システム既定)
アカウント有効                       Yes
アカウントの期限                     無期限

最終パスワード変更日時               2019/05/11 17:19:24
パスワード有効期間                   無期限
パスワード次回変更可能日時           2019/05/11 17:19:24
パスワードあり                       Yes
ユーザーによるパスワード変更可能     Yes

ログオン可能なワークステーション     すべて
ログオン スクリプト
ユーザー プロファイル
ホーム ディレクトリ
最終ログオン日時                     2023/08/21 00:00:00

ログオン可能時間                     すべて

所属しているローカル グループ        *docker-users
                                     *Users
所属しているグローバル グループ      *なし
コマンドは正常に終了しました。
```

以上。
[小ネタ] SpectaQL で任意の位置にページ内リンクを設ける

# 環境
- spectaql 2.0.4

# ドキュメント生成ツール SpectaQL
私は GraphQL API のドキュメント生成に [SpectaQL](https://github.com/anvilco/spectaql) を利用しています。
GraphQL スキーマからドキュメントを自動生成してくれるツールです。

https://github.com/anvilco/spectaql

# ページ内リンクを貼る
API の Description を書いていると、別の Type や Field の情報を前提に説明したい場合や、何度も同じ説明を書きたくないので、一箇所に説明を書いて関連箇所から参照させたい場合があります。
こういう場合にページ内リンクが使えると便利です。

SpectaQL は、標準で Query や Mutation、任意の Type などにアンカーを出力してくれます。
これらへのリンクを貼りたい場合は、単純にアンカー名を Markdown で指定するだけです。

| 種類 | アンカー名 |
| --- | --- |
| Query | `query-{queryName}` |
| Mutation | `mutation-{queryName}` |
| Subscription | `subscription-{queryName}` |
| Type, Union, Enum, etc | `definition-{typeName}` |

ただ、フィールドにはアンカーが出力されません。

# フィールドにアンカーを設置する
フィールドのアンカーが無いなら、自分で書いてしまえば良いわけです。

```graphql:schema.graphqls
type User {
  """
  <a id="field-User-name"></a>
  ユーザ名
  """
  name: String!
}

...

type Foo {
  """
  ...
  詳しくは [User#name](#field-User-name) を参照。
  """
  bar: String
}
```

応用として、 spectaql/config.yml などで共通仕様を記載するときに見出しにアンカーを設けておけば、任意の位置に参照を埋め込むことができるようになります。


```yaml:spectaql/config.yml
info:
  title: ほげほげ API
  description: |-
    これは、ほげほげ API の仕様書です。

    <a id="AboutErrors></a>
    ## エラー仕様
    | エラーコード | 発生理由 |
    | -------- | ------- |
    | ERROR_1  | xxxx |
    | ERROR_2  | yyyy |

```

# まとめ
Markdown の仕組みをわかっていれば当たり前の話ですね。
Field にページ内リンクしたいなぁと思いつつも、自分でアンカーを設置する発想が今までありませんでした。(アホですみません)
NixOS-WSLのshellを変更する方法 

 
NixOS-wslのshellを変更する方法を紹介します。

### 1, Linuxシステム上でX11サーバーへのアクセス権を変更する
```
sudo mount -o remount,rw /tmp/.X11-unix
```
変更しないと
```
fchmod() of /tmp/.X11-unix failed: Read-only file system
warning: error(s) occurred while switching to the new configuration
```
というエラーが出ます。


### 2,configuration.nixにzshをdefaultのshellを追加する

```diff_nix:/etc/nixos/configuration.nix
- { lib, pkgs, config, modulesPath, ... }:
+ { lib, pkgs, config, modulesPath,environment, ... }:

with lib;
let
  nixos-wsl = import ./nixos-wsl;
in
{
  ...
+  environment.systemPackages = with pkgs; [
+   zsh
+ ];
}
```
### 3,システムの設定ファイルの更新
```
sudo nixos-rebuild switch
```

上記の3ステップでNixOS-wslでのshellを変更できます。
Databricks にてネストしたアカウントグループへのUnity Catalog オブジェクトの権限付与に関する検証

## 概要

Databricks にてネストしたアカウントグループ（入れ子になったアカウントグループ）に対して、Unity Catalog オブジェクトの権限付与の可否に関する検証結果を共有します。5階層のグループを作成後、最上位のグループにオブジェクトへの権限付与を、最下位のグループへのユーザー割当を実施します。カタログへの権限付与後にスキーマを作成できたため、ネストしたアカウントグループに対して権限付与を実施できるようです。

Azure AD による SCIM プロビジョニング時には、ネストしたグループを Azure Databricks 側で管理する方法が次のように紹介されています。

> Databricks では、エンタープライズ アプリケーションを使用してユーザーとグループを同期し、Azure Databricks 内で入れ子になったグループとサービス プリンシパルを管理することをお勧めします。 

引用元：[プロビジョニングのヒント - Azure Databricks | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/databricks/administration-guide/users-groups/scim/aad#provisioning-tips)

## 検証内容

### 検証方法

次のような５つの階層のグループを作成して、`group_1`に対してカタログのオーナー権限を付与後に`group_5`のユーザーにてスキーマを作成の可否を確認します。

| #    | グループ名 | 概要                              |
| ---- | ---------- | --------------------------------- |
| 1    | group_1    | カタログへのオーナー権限付与、および、`group_2`を割当 |
| 2    | group_2    | `group_3`を割当                   |
| 3    | group_3    | `group_4`を割当                   |
| 4    | group_4    | `group_5`を割当                   |
| 5    | group_5    | ユーザーを割当 |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/da05a102-5fd2-95a0-030d-9c8b85f2e73e.png)


### 検証手順

#### 1. グループの作成とそれぞれのグループへのメンバーの割当

| #    | グループ名 | 概要                              |
| ---- | ---------- | --------------------------------- |
| 1    | group_1    | カタログへのオーナー権限付与、および、`group_2`を割当 |
| 2    | group_2    | `group_3`を割当                   |
| 3    | group_3    | `group_4`を割当                   |
| 4    | group_4    | `group_5`を割当                   |
| 5    | group_5    | ユーザーを割当 |

#### 2. 管理アカウントにてカタログの作成と権限付与を実施

```python
%sql
CREATE CATALOG IF NOT EXISTS group_test_g1

%sql
-- 権原付与
ALTER CATALOG group_test_g1 OWNER TO group_1;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/3a629832-1efe-a560-7b9f-9ad1038d4df2.png)

#### 3. `group_5`に割り当てたユーザーにてスキーマを作成できることを確認

```python
%sql
-- スキーマを作成できることを確認
CREATE SCHEMA IF NOT EXISTS group_test_g1.schema_01;
ALTER SCHEMA group_test_g1.schema_01 OWNER TO group_1;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/f49e3dcb-6051-f8ff-01e4-4da778b9626d.png)
Roblox で座った人の情報を取得する

以下がスクリプトになります。

```
Seat.ChildAdded:connect(function(child)
	if child.Name=="SeatWeld" then
		
		local character = child.Part1.Parent
		local player = game.Players:GetPlayerFromCharacter(character)

		if player then
    		-- YOUR FUNCTIONS HERE
		end
	end
end)

```

終わり。
Microsoft Defender for Endpoint （要件：Windows2016）

https://learn.microsoft.com/ja-jp/microsoft-365/security/defender-endpoint/configure-server-endpoints?view=o365-worldwide#prerequisites

https://www.catalog.update.microsoft.com/Search.aspx?q=KB5018411
1.2021 年 9 月 14 日以降のサービス スタック更新プログラム (SSU)

https://www.catalog.update.microsoft.com/Search.aspx?q=%09Windows+Server+2016
2.2018 年 9 月 20 日以降の最新の累積的な更新プログラム (LCU) 

KB4512574 1番目にインスト
KB4512745 2番目にインスト
KB3080149 3番目にインスト
KB4512745 4番目にインスト
KB4516045 5番目にインスト


https://www.catalog.update.microsoft.com/Search.aspx?q=KB4052623
3.Windows Updateを使用して、最新のプラットフォーム バージョン
 (Microsoft Defender Antivrus)

updateplatform.amd64fre_ee32214ec222e88de256030adb4f921e7cdb36da.exe
updateplatform.arm64fre_073a194d54f4e66f16012229ab6d08cef06d8ae5.exe
updateplatform.x86fre_1000e320f410525df9093dfcf486ac49b9010736.exe
リモートワークは生産性落ちません！（諸説あり）

※ 本記事は筆者の偏見と思い込みが強く反映された記事となるためご注意ください
※ 出社している方をリモートワーク派に引き込む意図はまったくありません
※ 所属する組織の公式見解ではありません
※ 絶対に悪用しないようお願いします

# 出社とリモートワークの差を考える
## 正直いってこれが一番。通勤時間がなくなる！

https://hataractive.jp/useful/5485/

令和3年の総務省の調べによると1日の通勤通学にかかる平均時間は**1時間19分**。
え、往復？！結構みんな移動に時間使ってないんだなぁ・・・（筆者は片道ドアドアで1時間10分ぐらい）
したら意外と移動あっても対して辛くないんじゃ・・

ちょっとまて

うーん、いや満員電車乗り継いできてるんすよ？あれは戦よ。移動後30分は体力の回復時間として必要ですね。
なので通勤時間は実質2時間19分ですね

え、朝の準備に必要な時間も通勤時間に含めろだって？
したらまぁ30分ぐらいだと仮定して2時間49分ですね

あー今日会社行きたくないなーの朝の10分もプラスすると
実質2時間59分ですね

うっわ、通勤に3時間て・・
時給1000円換算で3000円分じゃないですか。
1ヵ月20日出勤だとして6万ですよ・・って考えただけでモチベ下がって生産性落ちそうだわ・・

となるわけで、この3時間がなくなるというのは正直かなりでかいです！

## 飲み会が減る
私は飲み会が大好きです
大好きゆえ出社をしていると帰りにちょっと飲んでくかなんてことになるわけで、ちょっと飲みにいくと結構飲んじゃうわけです。結構飲んじゃうと二日酔いがきつい・・
それがリモートワークだとどうでしょう。
「ちょっと帰りに・・おや？もう家やん」
となるわけです
飲み会が減る＝二日酔いが減る
二日酔い時のパフォーマンスは通常時の5割減ぐらい
そこに寝不足をプラスすると9割減ですね

さらにですよ？
ゲリラ飲み会なんてものは大体１５時ぐらいにはある程度行く行かないの空気感て決まってるんですよ
そこで、パートナーと一緒に暮らしてる方をシュミレートしてみるとですよこうなるわけですよ

```
自分：「今日飲み会だからご飯いらないわー」
相手：「え？また？」
自分：「え？う、うん、ごめん付き合いでさ」
相手：「いやもう今日の夕飯の魚、解凍はじめちゃってるんだけど」
自分：「あ、そうだよね、ごめん」
相手：「ちゃんと早めに帰ってきてくださいね。」
自分：「は、はい、善処します」
```
※どこの家庭の話でもありません。フィクションです。

こんなやりとりを昼間っからやってみてくださいよ、飲み会開始までテンションだださがりで仕事どころじゃないですよ
パフォーマンス3割減ですね。

もうわかると思いますが、リモートワークの場合このような後ろめたい事の報告や二日酔いに悩まされることが減り、仕事に集中できるわけです！

## たばきゅー肯定派とたばきゅー否定派を分断でき、存在をブラックボックス化できる
たばきゅーとは、タバコ休憩の略ですね

元ヘビーたばきゅあー（なんだたばきゅあーって）が語る
なぜたばきゅーが否定されるか。それは当たり前に休憩時間の差それ自体ではなのではなかろうか。
タバコ1本吸うのに約5分、喫煙所までの移動含めるとまぁ7分〜10分というとこ
1時間ごとにヤニ切れを起こすので8時間×10分だとして、約80分・・
うっわ・・（「喫煙所では有意義な議論がなされているんだ！」論はここでは考えないものとする）

あとはその立ち振る舞いですよね
1時間に一回喫煙所に行くため立ち上がり、タバコの残量を確認。ニヤニヤして「喫煙所行かない？」などと同僚を誘いなんだったらコーヒー買ったり淹れたりのあの一連動作が良くないなぁと。しまいには時折聞こえる喫煙所からの大爆笑で真面目に働くみんなのとどめ刺しにいってる感あります。（あの頃はごめんなさい）

ただリモートワークであれば立ち上がる姿も残量確認やコーヒーをいれるさまも、大爆笑でとどめ刺されることもないわけで
ましてや「あれ〇〇さんってタバコ吸ってたんでしたっけ？」なんて知らない間に非喫煙者認定されてること間違いなしです

これでもうみんなのモチベ下げません！

## いくら残業したってなぜか疲れない
実際これないっすか？
正直ITの仕事って忙しい時は忙しいわけで、それなりに残業が必要になるケースってあるんですよね。。
こればっかりは避けられないんですよ。
勤務時間が増えるとなぜ疲れるかって、リラックスの時間と睡眠の時間が削られるからじゃないですか。
出社して3時間残業してみてください、19時退社が定時だと22時退社ですよ？
家着くの23時じゃないですか！！！
夕食、家事、風呂、etcで寝るの25時ぐらいにならないっすか？

ところがリモートワークであれば
まず残業3時間程度であれば全然許容範囲なんですよ
なぜかって？
**通勤には3時間かかるからですよ！それがなくなるならその分仕事したってまず平気なんですよ！（個人の見解です）**
たとえ寝るのが25時になろうとも、翌朝10時におきりゃあいいんですよ準備いらないんで（弊社は10時~19時勤務がベース）
それでも睡眠時間9時間なんです！！（寝すぎ。まだ働ける。）


# まぁ多分とんとんぐらいよ
とまぁ偏見に偏見をかさねて極端な仮定をふりかざしリモートワークの良さ、通勤との差をお伝えしたわけですが、いかがでしたでしょうか。
実際のところ、満員電車で格闘する時間や外にでる準備、多すぎる飲み会（w）がなくなるといままでそれに使っていた時間が空きますよね
私は実際その時間を仕事につかったり、家族との時間に使ったり、自己研鑽に使ったりしてかなり充実した毎日に変わったというのは事実です

一方で、リモートワークの悪いとこも当然あります。
あえてこの記事内では語りませんが、もし機会があれば別の記事にて深掘りしたいと思います

なのでまぁトントンぐらいですよ
どっちがいいとかどっちが悪いとか考えてないで、働きましょうか（泣）w
エンジニアとしての優秀さとアプリの面白さは関係するのか？

## 優秀なプログラマーは売れるアプリを作れるのか？
青春時代、音楽に没頭していた時からよく考えてたテーマなんやけど、例えば超絶技巧と言われるミュージシャンがいる。人間業とは思えない演奏スキルを持ってるんだよね。
で、そういったミュージシャン達が、本気を出せば良い曲を作れるかといえば別なんだよね。
ラスタファリのボブマーリーのNo woman no cryや日本では不良扱いだったビートルズのLet it be、自分で演奏すらしないヒップホップアーティスト達を例に出すまでもなく、シンプルで技巧を必要としないメロディーやコード進行、リズムの方が多くの聴衆のハートを奪っている。
3コードのロックやパンクは技巧とは対極にある。
フランクザッパやレイクレイプール、ジャコパトリシャスや村上ポンタ秀一、渡辺香津美といった、ミュージシャンズ　ミュージシャンの代表曲を何人の人が知っているであろうか？
ほぼ知らんであろう。
プログラムをやり出して、先輩エンジニアの人と話すときに毎回、こんな複雑なシステム作れるのに、なんで自分で何か作らへんのですか？という質問をしている。
殆どが、何作ってええか分かれへんし、とか、作ろうと思った事あるけど、めんどくさい　等という返答である。
技術屋として凄いのと、モノ作りの情熱を持ってるのは違うんだなあと改めて思う次第である。
モノを産み出すのに、一番重要なのは偏屈的な情熱と思い込みである。
時代を変えるプロダクツを産み出したスティーブ・ジョブズも技術はクリームソーダことウォズニアックである。
Facebookのザッカーバーグは元々プログラマーではあるが、プログラミングのレベルとしてはそれほど飛び出ていたわけではない。

[CS5でPHPやデータベースを語る若き日のザッカーバーグ](https://youtu.be/xFFs9UgOAlE)

## 何がおもしろいのかが分かる臭覚
で、結局売れるプロダクトを作る上で重要なファクターは、今何がおもろいか　が分かる臭覚とアイデア、それを徹底的に形にする情熱なんではないかなと。
その狂人の様なエネルギーが同じ様に少しおかしな技術者達を惹きつけ、アイデアとそれを現実する技術の両輪をなし、エネルギーに満ちたサービスとなる。

すでにブログ全盛期だった時代にわざわざ文字制限のあるtwitterがウケるとは思わんかったし、市井の素人が自分のプライベートを晒す様なSNSがこれほど多くの世界中の人の認証欲求を掘り起こすとは思ってなかったし、youtubeが覇権をとってる時代に短い素人のTiktok動画が世界を圧巻するとは思えなかったわけで、最初にこれがオモロイと感じ取ってどこか猥雑な香りのするサービスを立ち上げた一部の少しおかしい人達のアイデアというのは、やはり世間と折り合いをつけ、品行方正で凝り固まった世代からは出てこないんだろうなと、年々歳を取りながら、世の常識に疑問を持たない様に丸め込まれていく我が身を傍観しつつ思うところであります。
なので、攻撃的なアイデアを、オッサン達の集う会議でプレゼンしても無駄なんすよ。スーツを着たオッサン達が、満場一致でおもしろいというサービスがおもしろい訳がない。

プログラムが書ければ、何かおもろいものが作れるかもしれん　と思い2年ほど勉強してきてさて、ここらでなんか作ってこましたろ　と思った時に突き当たった、音楽理論や楽譜に強くなれば名曲が出来ると思っていたあの頃と同じ命題である。
Rails 6から7への移行で躓いたところ

Ruby on Railsのバージョンを6から7に更新するにあたって躓いたところの覚書です。

もちろん「ほとんど手を加えずに動いた」なんて主張するつもりはありません。ですが、とにかく動作させてみれば、基本的にはRails（というかRuby）の親切設計で、エラーになった時に「ここは〇〇しないといけないよ」みたいなメッセージが出てきますので、それに従ってエラーに対処することでだいたい何とかなります。

ただし、一ヶ所落とし穴（それも結構深い、、、）にはまりました。

# 落とし穴
上に書いたようにRailsが表示するメッセージに従ってエラーに対処していくことで、ある程度Rails 7で表示できるようにはなりました。ですが、ページネーションをしているページを表示しようとすると以下のようなエラーになってしまいます。

> ArgumentError in xxxxxx
>（中略）
> wrong number of arguments (given 4, expected 3)

で、その下には"<%= will_paginate %>"の行に赤く色が付いています。

## ページネーション
ここを読むような方には説明は不要と思いますけど念のため。

例えばものすごく行の多い表を表示させるときに、そのまま全部表示しようとすると、スクロールバーが大変なことになるとか、そもそもページの表示に時間が掛かりすぎるとかいろいろ嬉しくありません。なので一ページ当たり何行、と分割して表示することになるでしょう。これをページネーション(pagination)と言います。

# 無駄なあがき - その1
エラーメッセージからはwill_paginateの引数が間違っているように思えます。それに「will_paginateの直後にはページネーションの対象になるものを明示的に指定すべきだ」みたいな発言がネットにあったりします。

なので、will_paginateに引数を指定してみました。

が、同じようにエラーになるだけではなく、エラーメッセージにすら変化はありませんでした。え、どういうこと？

# 無駄なあがき - その2
こうなったらGoogle先生にお伺いを立てるしかありません。"ArgumentError"とか"wrong number of arguments (given 4, expected 3)"さらには"Rails"とか"pagination"とかをいろいろ組み合わせて検索してみます。

そうすると、なんかそれっぽいのが出てくることは出てきます。が、よくよく見ると"(given 4, expected 3)"の数が違うとか、かなり以前（Rails 5とか）の話だったりします。「will_paginate 3.1.6のバグだから3.1.7以上に更新すればよい」なんてものもありましたが、手元のwill_paginateのバージョンは4.0.0、、、

となると、will_paginateとかもっと根本的なところから作り直さないといけない？:scream::scream::scream:

# 解決
上に書いたエラーの下に「Application Trace | Framework Trace | Full Trace」というのがあります。そのうちの"Framework Trace"または"Full Trace"を選んでみます。すると以下のようなものが表示されます。
~~~
bootstrap-will_paginate (1.0.0) config/initializers/will_paginate.rb:33:in `previous_or_next_page'
will_paginate (4.0.0) lib/will_paginate/view_helpers/link_renderer.rb:63:in `previous_page' 
~~~
（初期状態（おそらく"Application Trace"）だと、自分の書いたerbファイルでエラーの発生した行しか表示してくれません。）

どうやらwill_paginateが呼び出しているbootstrap-will_paginateに問題があるようです。

この線で調べていくと、**bootstrap-will_paginateはBootstrapの3と4に対応しているけれども、どうやら最近のBootstrapは5らしい、ということが分かります。ということで、Bootstrap 5対応のbootstrap-will_paginate相当のgemを探しましょう**、ということになります。で、will_paginate-bootstrap-styleがそれに該当します。

この辺り、色々なところに断片的には書かれているのですが、ズバッと言い切っているのは以下のページくらいですね。

https://tomoyuki65.com/how-to-customize-a-rails-tutorial-to-create-a-portfolio/

以上より、Gemfileの
> gem 'bootstrap-will_paginate'

を
> gem 'will_paginate-bootstrap-style'

に書き換えて再挑戦です。

これでページネーションをしているページも問題なく表示できるようになりました。めでたし、めでたし。（表示が微妙に変わってしまっている可能性がありますが、漢（おとこ）なのでそういう細かいところは気にしません:sweat_smile:）

# おことわり
恒例のお断りですが、この文章の内容は、筆者が所属している会社・団体とは一切関わりがありません。いわゆる「自主的な研究の成果の発表」というものです。

また、今回「Bootstrap 5対応のbootstrap-will_paginate相当のgem」としてwill_paginate-bootstrap-styleを使ってますが、これが唯一の解なのか、最善の解なのかについては一切確認していません。手元で表示できて満足してしまったもので。
Javaで「読み込みの事前確認」の動作を確認してみた

# 概要
Javaで「読み込みの事前確認」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/stream/index2.html

# 実装
以下のファイルを作成しました。
```StreamTest2.java
import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;

class StreamTest2{
  public static void main(String args[]){
    try{
      File file = new File("test.txt");

      if (checkBeforeReadfile(file)){
        FileReader filereader = new FileReader(file);

        int ch;
        while((ch = filereader.read()) != -1){
          System.out.print((char)ch);
        }

        filereader.close();
      }else{
        System.out.println("ファイルが見つからないか開けません");
      }
    }catch(FileNotFoundException e){
      System.out.println(e);
    }catch(IOException e){
      System.out.println(e);
    }
  }

  private static boolean checkBeforeReadfile(File file){
    if (file.exists()){
      if (file.isFile() && file.canRead()){
        return true;
      }
    }

    return false;
  }
}
```
以下のコマンドを実行しました。
```
$ javac StreamTest2.java 
$ java StreamTest2 
This is a test file.
```

# まとめ
何かの役に立てばと。
Mackerel でサービスメトリックに一発で飛ぶ機能

サイドバーの「サービス」の横あたりにマウスカーソルを持っていくと、`S` というボタンが出てきます。これを押すと、該当サービスのサービスメトリック画面に一発で飛ぶことができます。便利ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276/468a48fc-e9be-e80b-68ee-fc23fdf71fad.png)
TCC.db のテーブル名・カラム名一覧を取得する

### シェルスクリプト
```sh
TCC_DB_PATH=~/Library/Application\ Support/com.apple.TCC/TCC.db

function execute() {
  sqlite3 "$TCC_DB_PATH" "$1"
}

table_names=`execute ".table"`
for table_name in $table_names; do
  column_names=`execute "SELECT name FROM pragma_table_info('$table_name')"`
  for column_name in $column_names; do
    echo "$table_name:$column_name"
  done
done
```

### 出力
```plaintext
access:service
access:client
access:client_type
access:auth_value
access:auth_reason
access:auth_version
access:csreq
access:policy_id
access:indirect_object_identifier_type
access:indirect_object_identifier
access:indirect_object_code_identity
access:flags
access:last_modified
active_policy:client
active_policy:client_type
active_policy:policy_id
expired:service
expired:client
expired:client_type
expired:csreq
expired:last_modified
expired:expired_at
access_overrides:service
admin:key
admin:value
policies:id
policies:bundle_id
policies:uuid
policies:display
```
python実行環境にインストールされているpipパッケージを一覧表示する

## 用途
* クラウド上のPython実行環境だと、どのパッケージがインストールされているかわからないことがある
    * (ドキュメンテーションされていても更新されてなかったり）
* そういう環境で使えるパッケージをぱっと確認するのに使える

```python
import pkg_resources
import pprint

installed_packages = pkg_resources.working_set
installed_packages_list = sorted(["%s==%s" % (i.key, i.version)
   for i in installed_packages])
pprint.pprint(installed_packages_list)
```
パッとメモ取りたい時のエイリアス

## やりたいことと条件

- MTGやプチ相談の際、頻繁にメモを取る
- 閲覧者は基本自分のみ
  - 共有する際は編集する
- ターミナルと睨めっこしていることが多いのでメモ帳とかチャットツールじゃ無い方が楽かもな
  - マークダウンで書きたいな 
- １つ書き終えたら手作業リネームでも良いや

## 設定

- `~/.bash_profile`に以下の3行を追記
  - パスは管理しやすい場所、適当で大丈夫です
- `source ~/.bash_profile`するかターミナル再起動

```bash
alias memos='cd /Users/ユーザー名/tools/script/Stacker/ && ls -lahG';
alias memo='vim /Users/ユーザー名/tools/script/Stacker/`date "+%Y%m%d"`.md';
alias memocode='code /Users/ユーザー名/tools/script/Stacker/`date "+%Y%m%d"`.md';
```

## 簡単な解説

- memos
  - メモの保存先へカレントディレクトリを移動
- memo
  - 今の日付でマークダウンファイルを新規作成
- memocode
  - memoのVSCode用(VSCode使ってない場合は記述しなくてもOK)

## その他

- dateコマンドのフォーマットに時間なども加えるとより便利になるかもしれない