OmniAICreator/Qiita-1.07M huggingface dataset:
ファイルサイズが 0 のファイルを削除するワンライナー

# よりエレガントな方法!

記事を書いた後に @ko1nksm さんよりコメントをいただきました。

```
find . -size 0 -delete
```

これでOK!

以下は余計に手間がかかっている解法です。

# 無駄な作業!


録画失敗でサイズゼロのファイルができたので整理。

```
# ls -al | awk '$5==0 {print $0}'
-rw-r--r-- 1 root     video              0  9月  9 00:02 2022年09月08日23時30分00秒-アニメ　Shenmue the Animation　第10話　廻天（かいてん）.mp4
-rw-r--r-- 1 root     video              0  9月  9 20:01 2022年09月09日19時30分00秒-機動戦士ガンダム 鉄血のオルフェンズ　第11話「ヒューマン・デブリ」.mp4
-rw-r--r-- 1 root     video              0  9月 10 02:27 2022年09月10日01時55分00秒-惑星のさみだれ　♯１０「ヘカトンバイオンと獣の騎士団」【アニメイズム】[字] .mp4
-rw-r--r-- 1 root     video              0 10月  8 05:07 2022年10月08日01時00分00秒-アイドルマスター シンデレラガールズ　第１話「Who is in the pumpkin carriage？」.mp4
```


ここで注意するべきは、ファイル名に半角スペースが入っているのがある。



# 環境

```
# cat /etc/issue
Ubuntu 20.04.4 LTS \n \l
```


# step-to-step


まずは、ファイルサイズがゼロのファイル名をリストアップ。find でやってもいいけど今回は awk で。

```

# ls -al | awk '$5==0 {print $9}' 
2022年09月08日23時30分00秒-アニメ　Shenmue
2022年09月09日19時30分00秒-機動戦士ガンダム
2022年09月10日01時55分00秒-惑星のさみだれ　♯１０「ヘカトンバイオンと獣の騎士団」【アニメイズム】[字]
2022年10月08日01時00分00秒-アイドルマスター
```

ファイル名がスペースで切れてしまってますね。
なので、ファイル名をダブルクォートで囲んだものを入力として、一度スペース区切りでサイズゼロを抽出します。

```

# ls -alQ | awk '$5==0 {print $0}' 
-rw-r--r-- 1 root     video              0  9月  9 00:02 "2022年09月08日23時30分00秒-アニメ　Shenmue the Animation　第10話　廻天（かいてん）.mp4"
-rw-r--r-- 1 root     video              0  9月  9 20:01 "2022年09月09日19時30分00秒-機動戦士ガンダム 鉄血のオルフェンズ　第11話「ヒューマン・デブリ」.mp4"
-rw-r--r-- 1 root     video              0  9月 10 02:27 "2022年09月10日01時55分00秒-惑星のさみだれ　♯１０「ヘカトンバイオンと獣の騎士団」【アニメイズム】[字] .mp4"
-rw-r--r-- 1 root     video              0 10月  8 05:07 "2022年10月08日01時00分00秒-アイドルマスター シンデレラガールズ　第１話「Who is in the pumpkin carriage？」.mp4"
```

ここから、もう一度 AWK をかけてファイル名だけを取り出します。

```
# ls -alQ | awk '$5==0 {print $0}' | awk -F\" '{print $2}'
2022年09月08日23時30分00秒-アニメ　Shenmue the Animation　第10話　廻天（かいてん）.mp4
2022年09月09日19時30分00秒-機動戦士ガンダム 鉄血のオルフェンズ　第11話「ヒューマン・デブリ」.mp4
2022年09月10日01時55分00秒-惑星のさみだれ　♯１０「ヘカトンバイオンと獣の騎士団」【アニメイズム】[字] .mp4
2022年10月08日01時00分00秒-アイドルマスター シンデレラガールズ　第１話「Who is in the pumpkin carriage？」.mp4
```
# 本番

うまくできたので、これを使ってシェルコマンドリストを作ります。

```
# ls -alQ | awk '$5==0 {print $0}' | awk -F\" '{print "rm \""$2"\""}'  
rm "2022年09月08日23時30分00秒-アニメ　Shenmue the Animation　第10話　廻天（かいてん）.mp4"
rm "2022年09月09日19時30分00秒-機動戦士ガンダム 鉄血のオルフェンズ　第11話「ヒューマン・デブリ」.mp4"
rm "2022年09月10日01時55分00秒-惑星のさみだれ　♯１０「ヘカトンバイオンと獣の騎士団」【アニメイズム】[字] .mp4"
rm "2022年10月08日01時00分00秒-アイドルマスター シンデレラガールズ　第１話「Who is in the pumpkin carriage？」.mp4"
```


削除系になるのでスクリプトから削除を実行するのではなく、一度ファイルに落とします。

```
# ls -alQ | awk '$5==0 {print $0}' | awk -F\" '{print "rm \""$2"\""}'  > rmsizezero.sh
```
# 削除実行

中身確認して問題なければ実行します。

```
# bash rmsizezero.sh
```

消えたかどうか確認

```
# ls -alQ | awk '$5==0 {print $0}' | awk -F\" '{print $0}'
# 
```
うまくいったみたいです。

# 課題

ファイル名をダブルクォートで囲って、半角スペースなどのエラーを回避していますが、ファイル名にダブルクォートが入っていたらうまくいきません。問題文字をエスケープする方法がより良いでしょう。

# おまけ

今回、rmsizezero.sh も一緒に消えてしまいます。それはそれで面白い。
AndroidStudioのStructureとは

 今回はStructureが便利だと思ったので書いておこうと思います。

例えば既存のプロジェクトに後から入った場合に、対象のコードを探したり、大きめのクラスで関数の呼び出し元を探したりしてると、あそこの処理どこだったけ？となったりすることありませんか？

その時にStructureは便利だと思いました。

クラス内の関数一覧が出てきます。

場所はAndroidStudioの左下の方にあります

![スクリーンショット 2022-10-16 11.46.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/9eba71e1-b1f6-7a16-88e2-405423c5791b.png)

鍵のマークでprivateの関数を表示させる表示させないを選べたりします。
関数名は思えている場合アルファベット順の並び替えも出来たりするので、クラス内のコードをスクロールしながら、探す必要がなくなります！


以上です！
Pythonのリスト、タプルについて

# はじめに
複数の値を扱えるのは分かる。違いはちゃんと説明できない。
なんとなくでも説明できるレベルになりたいのでまとめた。

# リスト(list)
リストは要素(中身)の挿入と削除ができる。
インデックス番号で要素にアクセスできる。

## 初期化
```python:test.py
# 初期化
mylist=[]
print(f'mylistの形式: {type(mylist)}')
print(f'mylistの中身: {mylist}')```
```
↓実行結果
```
# python test.py
mylistの形式: <class 'list'>
mylistの中身: []
```
`mylist=[]`で行っている初期化は、`mylist=list()`とも記述できる。
### 初期化時の注意
```python:test.py
# 初期化
mylist = list("MY LIST")
print(f'リスト: {mylist}')
```
↓実行結果
```
# python test.py 
リスト: ['M', 'Y', ' ', 'L', 'I', 'S', 'T']
```
list()を使って初期化のつもりが、1文字ずつリスト化されました。
MY LISTというstr型の文字列をリスト型に変換したため、1文字ずつのリストになりました。
`mylist = ["MY LIST"]`として初期化しましょう。

## データの追加
リストの後ろに追加するときは`append`、任意の場所に追加するときは`insert`を使う。
```python:test.py
# 要素をひとつ追加
mylist.append('A')
print(f'要素をひとつ追加: {mylist}')

# 要素をまとめて追加
add_list = ['B','C','D','E']
for add in add_list:
  mylist.append(add)
print(f'要素をまとめて追加: {mylist}')

# 任意の場所に追加
mylist.insert(3,'Z')
print(f'任意の場所に追加: {mylist}')
```
↓実行結果
```
# python test.py
要素をひとつ追加: ['A']
要素をまとめて追加: ['A', 'B', 'C', 'D', 'E']
任意の場所に追加: ['A', 'B', 'C', 'Z', 'D', 'E']
```
## 要素にアクセス(取り出す)
```python:test.py
# 初期化
mylist=['A','B','C','D','E']

# 要素にアクセス
print(f'2番目の要素にアクセス: {mylist[1]}')
```
↓実行結果
```
# python test.py
2番目の要素にアクセス: B
```
リストは一番頭の要素が0から数え始めるので、2番目の文字は`[1]`でアクセスする。

## 書き換え
```python:test.py
# 初期化
mylist=['A','B','C','D','E']

# 要素の一部をリストに書き換え
mylist[4] = ['E','F','G']
print(f'要素の一部をリストに書き換え: {mylist}')
```
↓実行結果
```
# python test.py
要素の一部をリストに書き換え: ['A', 'B', 'C', 'D', ['E', 'F', 'G']]
```
リストの中にリストを入れることもできます。

## 削除
```python:test.py
# 初期化
mylist=['A','B','C','D','E','D','F','D','G','D']

# 要素を削除(インデックス指定)
del mylist[0]
print(f'1番目の要素を削除: {mylist}')

del mylist[0:2]
print(f'1〜2番目の要素を削除: {mylist}')

# 指定した文字列を削除
mylist.remove('D')
print(f'Dを削除(最初の1文字だけ): {mylist}')

# 重複削除
del_list_dup = list(set(mylist))
print(f'重複削除: {del_list_dup}')

# 指定文字のみ削除(指定文字以外を残す)
del_list_not = [s for s in mylist if s != 'D']
print(f'指定文字のみ削除: {del_list_not}')

# 指定文字以外を削除(指定文字のみ残す)
del_list_eq = [s for s in mylist if s == 'D']
print(f'指定文字以外を削除: {del_list_eq}')
```
↓実行結果
```
# python test.py 
1番目の要素を削除: ['B', 'C', 'D', 'E', 'D', 'F', 'D', 'G', 'D']
1〜2番目の要素を削除: ['D', 'E', 'D', 'F', 'D', 'G', 'D']
Dを削除(最初の1文字だけ): ['E', 'D', 'F', 'D', 'G', 'D']
重複削除: ['E', 'G', 'F', 'D']
指定文字のみ削除: ['E', 'F', 'G']
指定文字以外を削除: ['D', 'D', 'D']
```

# タプル(tuple)
タプルは書き換えができない形式。
リスト⇔タプルの相互変換が可能。
```python:test.py
# 初期化
mylist = ['A','B','C','D','E']

# タプルに変換
mytuple = tuple(mylist)

# 確認
print(f'データの確認: {mytuple}')
print(f'型の確認: {type(mytuple)}')

# 要素を取得
print(f'3番目の要素を取得: {mytuple[2]}')
```
↓実行結果
```
# python test.py 
データの確認: ('A', 'B', 'C', 'D', 'E')
型の確認: <class 'tuple'>
3番目の要素を取得: C
```
タプルを初期化する場合は、`mytuple = ('A', 'B', 'C', 'D', 'E')'としてやればよい。
タプルからリストへの変換は、`list(mytuple)`で変換できる。
Drupalの便利なモジュールの紹介

# Drupal 便利なモジュール

## **Examples for Developers**

### 機能説明

Drupalの開発のサンプルが記載されています。

例：`examples/module/field_example`であればFieldType, FieldFormatter, FieldWidgetを使った実装例が記載されています。

### 使い方

1. exampleをインストールする
    1. `composer require 'drupal/examples:^3.0’`
2. モジュールを有効化
3. 使いたいサンプルのモジュールを有効化する
    1. 利用できるモジュールは`examples/module/`配下にある

Link：[https://www.drupal.org/project/examples](https://www.drupal.org/project/examples)

---

## JSON:API

### 機能説明

Drupalで作成されるJsonを確認することができる

### 使い方

1. jsonapiモジュールを有効化する
2. `/jsonapi/node/ { コンテンツタイプ} /`へアクセスをする
    1. 例）汎用ページの場合：`/jsonapi/node/free_content/`
3. 対象コンテンツの date.href のURLにアクセスする

Link：[https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module](https://www.notion.so/Drupal-225b88ec413a4029a980fbfba1cbfcc6)

---

## **Devel**

### 機能説明

devel_generateを使うことでコンテンツのダミーデータを作成することができる

### 使い方

1. develのモジュールをインストール
2. develの有効化
3. devel_generateの有効化
4. 管理画面 > 環境設定 > Generate > コンテンツ生成 etc…

Link：[https://www.drupal.org/project/devel](https://www.drupal.org/project/devel)
AWS SAM CLIをbrew installしたときに発生したエラーを解決する

# 前提
以下のURLの手順に沿ってAWS SAM CLIをインストールしたときにエラーでハマりました。

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-mac.html

# 環境
- macOS: 12.6

# エラー内容
実行したコマンドはこちらです。
```console
brew install aws-sam-cli
```

そしてこれがエラー内容です。
```console
Error: python@3.8: the bottle needs the Apple Command Line Tools to be installed.
  You can install them, if desired, with:
    xcode-select --install

You can try to install from source with:
  brew install --build-from-source python@3.8
Please note building from source is unsupported. You will encounter build
failures with some formulae. If you experience any issues please create pull
requests instead of asking for help on Homebrew's GitHub, Twitter or any other
official channels.
```

`xcode-select --install`を使用すると膨大な時間がかかると思ったので、python3.8をインストールすることにしました。
結果的に成功しました。

```console
(base) XXX $ brew install aws-sam-cli
==> Downloading https://github.com/aws/aws-sam-cli/releases/download/v1.60.0//aws-sam-cli-1.60.0.sie
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-2e65be/92
######################################################################## 100.0%
==> Installing aws-sam-cli from aws/tap
==> Pouring aws-sam-cli-1.60.0.sierra.bottle.tar.gz
🍺  /usr/local/Cellar/aws-sam-cli/1.60.0: 4,644 files, 112.3MB
==> Running `brew cleanup aws-sam-cli`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
(base) XXX $ sam --version
SAM CLI, version 1.60.0
```
Git コマンド集

# Git command集

### ファイルの追加、コミット

```bash
git add ファイル名
```

```bash
git commit -m "コメント"
```

### ファイルをアップ

```bash
git push origin ブランチ名
```

### git log

```bash
git log
```

[]()

ツリーの整形

```bash
git log --graph --pretty=format:"%h %ad %s"
```

### rebase

```bash
git rebase ブランチ名　// 起点となるブランチ
```

[これで完璧! 図解でわかるgit rebaseの2つの使い方! | 侍エンジニアブログ](https://www.sejuku.net/blog/71919)

### 変更を退避させる(stash)

```bash
git stash save "コメント"
```

退避の一覧確認

```bash
git stash list
```

退避をもとに戻す

```bash
git stash applay "戻したいstash番号"
```

退避したものをもとに戻してリストから消す

```bash
git stash pop "戻したstash番号"
```

### コミット間の差分

```bash
git diff <コミットID1> <コミットID2>
```

### コミット間の差分ファイル一覧確認
NextJS で作成したアプリを PWA化する

## 目的

NextJS で作成したアプリを PWA 化するときの手順をメモ。

## 手順

### 1. manifest.json を作成
```
{
  "name": "App Name",
  "short_name": "App Name",
  "icons": [
    {
      "src": "./logo-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "./logo-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "theme_color": "#ffffff",
  "background_color": "#004740",
  "display": "standalone",
  "orientation": "portrait",
  "scope": "/",
  "start_url": "/"
}

```

`icons` は最低でも192px と 512px の２つが必要。

> For Chromium, you must provide at least a 192x192 pixel icon, and a 512x512 pixel icon. 

引用元: https://web.dev/add-manifest/#icons

`display` は、`standalone` を指定する事で、Native アプリのように、アドレスバーを非表示にしたり、通常のブラウザとは別でアプリを表示できるようになる。

`orientation` は、"portrait" を指定する事で画面を縦向きに固定できる。
その他のオプションは、[「Nuxt.js(SPA)のWebサービスにmanifest.jsonを置くだけでホームに追加できるようになった」](https://qiita.com/kira_puka/items/d99683f6dc65a478e6d9#orientation)という記事で分かりやすく解説してくれています。


### 2.必要なファイルを読み込む

`_document.js` もしくは、`_app.js` で、manifest.jsonなどを読み込む。

```
import Document, { Html, Head, Main, NextScript } from "next/document";

class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          <link rel="manifest" href="/manifest.json" />
          <link rel="apple-touch-icon" href="/icon.png"></link>
          <meta name="apple-mobile-web-app-capable" content="yes"/>
　　　　　　<meta name="mobile-web-app-capable" content="yes" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;
```

### 3.next-pwa をインストール

```
$ npm install next-pwa --save
```

### 4. next.config.json を設定

`next.config.json` を以下のように設定。

```
const withPWA = require('next-pwa')({
  dest: 'public'
})

module.exports = withPWA({
  // next.js config
})
```

で、`npm run build` をすると、`public/` ディレクトリ内に、`sw.js`と`workbox-***.js` が生成される。これが servicework 用のファイル。自動で読み込まれる。

このファイルはビルド時に毎回生成されるので、`.gitignore` に以下のように追記しておく

```
**/public/sw.js
**/public/workbox-*.js
**/public/worker-*.js
**/public/sw.js.map
**/public/workbox-*.js.map
**/public/worker-*.js.map
```

## 備考

- apple-touch-icon の背景が透明だと、クリックして拡大表示までの背景が透明になり（デフォルトはbackground-color が適用？）不自然なので、アイコン側で色をつける事

## 参考
- https://dev.to/anuraggharat/pwa-with-nextjs-5178
- https://github.com/shadowwalker/next-pwa
- https://developer.mozilla.org/ja/docs/Web/Progressive_web_apps
質問することは決して恥ずかしいことではない！

# 自分がほしい答えをうまく引き出す方法

今回は質問の投げかけ方、質問の仕方について話していきたいと思います。

自分がほしい答えをうまく相手から引き出す方法の紹介です。

## 質問をすることに抵抗ありますか？

質問をすることに対して抵抗はありますか？

僕は新卒で入社した時先輩に質問する時、

:::note warn
こんなこと思ったことありますか？
- 「迷惑ではないか？」
- 「時間を奪ってしまうのではないか？」
- 「この先輩に質問しづらいな」
- 「こんなこと聞いていいのか？」
:::


こういったことを考えてしまい、最初は聞くことに抵抗がありました。

**ただ、今挙げたようなことを気にする必要はありません。**

それはなぜかというと質問することにはたくさんのメリットがあるからです。

## 質問をすることのメリット

質問をするメリットはいくつかありますが、私がこれまで質問をしてきてメリットだと思ったこと

- 効率よく問題を解決できる
- 問題解決能力が身につく
- より深い知識を学ぶことができる
- 何がわかっていて、何がわかっていないのかを伝えることができる

### 効率よく問題を解決できる
最初はわからないことがわからないと言ったことがあるでしょう。
そういったときはどんなに考えても解決には至りません。
こういったことは質問をすることで、知識がある人からの助言や調べ方を教えてもらおうことで効率よく解決することができます。

### 問題解決能力が身につく
質問をするときは、情報の整理をしてから質問をしますよね？

- 原因がなにか
- どうしてそうなったか
- 解決方法はなにか
- 仮説を立てる

といったことを考えるようになり、こういったことを繰り返すことで問題解決能力が自然と身につきます。

### より深い知識を学ぶことができる
質問をしたあとに、これまでわからなかったことがわかるようになります。
また、質問したことに対してわからない言葉や技術的な知識が出てくると思います。それを調べることや更に質問することで知識といて身につきます。

### 何がわかっていて、何がわかっていないのかを伝えることができる

何がわかっていて何がわかっていないのかを伝えることができます。
**これは、自身のメリットではなく相手のメリットになります。**

相手がどこまで理解しているのかや次タスクを降るときはどの粒度の説明でタスクを降ることができるのかを把握することができます。

質問は自分だけではなく、相手にもメリットが有ることを頭に入れておくと質問をする抵抗が薄くなると思います。

## 質問のレベル（無知のレベル）

自分が今その作業でどの段階にいるのかを確認してみましょう。

```markdown
- **0OI: 全部分かっている**
    - 「答え」を持っている。あとは書き写すだけで完成する。
- **1OI: 分からないことが分かっている**
    - 答えを得るための「質問」を持っている。
- **2OI: 分からないことが分からない**
    - 「質問」を持たない状態。決定的な答えを引き出すための「質問」ができない。
- **3OI: 分からないことが分からない状況を何とかする術を知らない**
    - 2OI→1OI→0OIと進んでいくためのプロセスがない状態です。
- **4OI: 無知にレベルがあることを知らない**
```
https://qiita.com/seki_uk/items/4001423b3cd3db0dada7

これによって質問の投げかけ方も変わって来ると思います。

## 質問する前に意識すること

1. 自分で調べること
1. 同じ質問をしないこと
1. 相手の時間をなるべく奪わないこと

まず、１つ目がまずは自分で調べるについて、エラーが出たからと言って、すぐに質問をすることがNGです。
自分である程度調べてから質問をするようにしましょう。

２つ目は同じ質問をしないことです。
質問をして問題が解決したら、メモを取るようにしましょう。社内の人間であれば同じ質問をしても問題はないでしょう。
ただ、案件でお客様に同じ質問を何度もした場合はどうでしょうか。

「この人前回も同じ質問をしてきたよね。。。」

と言った印象を与えてしまいます。なので、同じ質問はなるべくしないようにしましょう。

３つ目は相手の時間をなるべく奪わないように気をつけることです。
これは一つ前で話したことともつながっていますが、同じ質問は相手の時間をただ奪ってしまうことになります。

また、何も調べない状態で質問をすると、状況の確認や原因の調査などからやり取りが発生してしまうので、情報をまとめてから質問をするのとでは解決する時間が大幅に変わってきます。

では、どのタイミングで質問をするのがいいのか。

これは一概には言えませんが、１５分を目安に考えるといいと思います。

Googleの人工知能チームが１５分ルールというものを採用しています。これは、１５分考えてもわからない場合は質問をすると言ったことになります。

これを目安にするといいと思います。

## 目的を明確にする

次に目的を明確にすることです。自分はどうしたいのかを明確にしましょう。

::: note
そこでポイントになってくるのが一番知りたいことを最初に伝えること
:::

手順がわからない場合 → 自分がやっている手順があっているのか

実装方法がわからに場合 → 次に何をやればいいのか

エラーが出たとき → エラーの解消方法

などを一番最初に聞くことで何を解決したいのかが明確になり、回答する側も答えやすくなると思います。


## 状況と伝える

次に、状況を伝えることです。

ここで、大事になってくるポイントとしては３つ。

まずひとつ目が、

1. 事実を伝える
2. 曖昧な言葉を使わない
3. 正確に情報を伝える

と言ったことになります。

まずは、事実を伝えることです。

- 何が起きているのか
- エラー内容
- 原因は無いか
- 何を解決したいのか

こういったことを伝えることで、お互いに状況を把握することができます。

次に、曖昧な言葉を使わないことです。

「これ」、「あれ」など曖昧な言葉や、理解しているふりをしてしまうことなどは避けましょう。

わからないことは恥ずかしいことではないので、理解している範囲内で伝えることが重要です。

最後に情報を正確に伝えることです。

よくあるのが、説明を省力してしまうことや言わなくても相手はわかってくれる妥当という予想をしてしまうことです。

予想することや仮説は重要ですが、質問するにおいてはあまりいいことでは無いです。

曖昧な言葉を使うことや情報を正確に伝えないことによって「返ってややこしくなる」ケースもあります。

なので、今自分が理解している状況と実際に何が起こっているのかを正確に伝える必要があります。

## 最後にかならず復習する

復習は必ずしましょう。

１回で理解できるに越したことは無いですが、これはなかなか難しいです。

内容によっては１回で理解できることもあリマスが、１回で理解できないことも多くあります。

なので、復習できるようにメモをとること、自分が理解しやすいようにまとめる、理解できなかったことは理解できるまで聞くなどをして、１つずつ問題を解決していくことをおすすめします。
ABC273メモ

0.はじめに
　Cまではそこそこの歯ごたえで溶けましたが、D以降は処理時間を
　減らす工夫をする前に時間切れといった感じでした。

1.A - A Recursive Function
　階乗を求める問題かなと思いつつ、素直にN回のfor文を作成。
　ところがうまくいかずWhile文にしてもNG。
　よく見たら”*=”を使っているのに、=の後にも元の変数を入れているという
　凡ミスをしてて変に時間を食ってしまいました。

　https://atcoder.jp/contests/abc273/submissions/35667109

2.B - Broken Rounding
　最初にググったらpythonにround関数があると知り、それを軸に実装。
　ところが、さらに調べるとうまく四捨五入できないことを知り、やり直し。

　実装内容
　1)iを1～Kまで回す
　　2)変数chkに10のi乗をセット
　　　　i=1の時、chk=10
　　3)変数chk2に10のi-1乗に5をかけたものをセット
　　　　i=1の時、chk=5
　　4)変数mXにXをchkで割った余りをセット
　　　　i=1の時、mXは1桁目の値
　　　　5)mXがchk2以上の時→切り上げ対象
　　　　　　XからmXを引き、chkを足す
　　　　6)mXがchk2より小さい時→切り捨て対象
　　　　　　XからmXを引く
　7)Xを出力　

　https://atcoder.jp/contests/abc273/submissions/35674948

3.C - (K+1)-th Largest Number
　考え方
    最初問題の意図を取り違え失敗
　　誤）リストのi番目の数値より大きい数の個数を表示
　　正）リスト内に自らより大きい数字の種類がi個ある数値が何個あるかを表示

　実装内容
　　(1)リストAを並べかえたリストsortAを用意
　　(2)辞書dictを用意（keyは自分以上種類数カウント、値は同値を持つ数値数）
　　(3)自分以上の種類数カウント用変数cntを用意
　　(4)初期処理としてsortA[0]の処理
　　　　dict[0]に1をセット
　　　　比較用変数preにsortA[0]をセット
　　(5)iを1からNまで繰り返し
　　　　(6)sortA[i]!=preの時cntに1を加算し、dict[cnt]に1をセット
　　　　(7)sortA[i]=preの時、dict[cnt]に1を加算
　　　　(8)cntにsortA[i]をセット
　　(9)出力処理：iを0からNまで繰り返し
　　　　(10)dict内にkey=iがある場合値を表示
　　　　(11)dict内にkey=iが無い場合0を表示

　https://atcoder.jp/contests/abc273/submissions/35681088

4.D - LRUD Instructions
　単純に問題通りの実装をしてみたところTLE
　その時点で残り時間10分くらいだったのでEを覗いて終了

5.E - Notebook
　単純に実装したら、”DELETE”だけsplitがエラーになって躓いているうちに時間切れ
　変なところで引っかかってしまいました。（それが無くても解けてないとは思いますが・・・）

D・Eも面白そうな問題だったので今週時間があったら振り返りたい・・・・と思いつつすぐ
翌週になってしまいますね。
【Terraform】Terraformで外部から変数を与える方法

# はじめに
udemyを使ってTerraformの勉強をしたので、Terraformで外部から変数を与える方法についての学習備忘録です。

https://www.udemy.com/course/iac-with-terraform/

# 外部から変数を与える方法は３種類

* 外部から変数値を与える方法は3種類あります
* 3種類の方法で同じ変数を並行して指定することも可能です
    * 環境変数 < 変数ファイル < コマンド引数の順で```上書き```します
    * 同じ方法で変数の定義が重複した場合は原則として```後に定義した変数が優先```されます

## 環境変数
環境変数へあらかじめ設定してある値を利用します
```terraform
TF_VAR_【Name】
```

## 変数ファイル
あらかじめ決められた変数ファイル名のファイルに指定します

```terraform
terraform.tfvars
```

## コマンド引数
以下のコマンド引数で指定された値を利用します

```terraform
-var 【NAME】＝【NAME】
-var-file【FILE_PATH】
```

# 環境変数を使った上書き

```terraform:main.tf
variable "name" {
  type    = string
  default = "nothing"
}
```

TF_VAR_<NAME>で上書きできます
環境変数定義、プラン実行

```zsh
$ export TF_VAR_name="hello" 
$ terraform plan

#　実行結果
> tags = {
    + "Name" = "hello"
```

# 変数ファイル（terraform.tfvars）で上書き
変数ファイルの拡張子は```.tfvars```

```terraform:terraform.tfvars
name = "hoge"
```

```terraform:main.tf
variable "name" {
  type    = string
  default = "nothing"
}
```

プラン実行
```zsh
$ terraform plan

#　実行結果
> tags = {
    + "Name" = "hoge"
```

# コマンドを使った上書き

```terraform:main.tf
variable "name" {
  type    = string
  default = "nothing"
}
```

プラン実行
```zsh
$ terraform plan -var name="command" 

#　実行結果
> tags = {
    + "Name" = "command"
```

# 変数の上書きの使い分け

## 環境変数
実行ログに残らない

* 鍵情報など（ファイルとして残したくない情報）
* 環境依存情報（dev stg prd）など
* 運用管理サーバーで作業するような厳格な場合

## 変数ファイル
基本的にはこちらの方法がおすすめ（変数は別ファイルで外だし）

* git管理できる=構成管理として残せる
* ロジックとデータ(変数)を切り離すことで変更箇所が分かりやすくなる 

## コマンド引数
実行ログに残る

* テストで部分的に変更したい
* デバッグで一部変更したい
* など、一時的な利用


以上。本日は、Terraformで外部から変数を与える方法についてをまとめてみました。
お家サーバー その7

# 概要
お家サーバーやってみる。
wordpressやってみた。
javascript投稿してみた。

# 手順

- 新規投稿クリック。
- カスタムHTMLブロックを追加。
```
<script>
alert("ok");
</script>
```

- 公開する。


以上。
Salesforce上級アドミニストレーター試験の公式サンプル問題解説してみた-01

こんにちは
本橋孝昭です



今回の内容は動画でも解説しています

https://www.youtube.com/watch?v=7CX10P0eT-w

<iframe width="560" height="315" src="https://www.youtube.com/embed/7CX10P0eT-w" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Salesforce上級アドミニストレーター試験の公式サンプル問題があるのはご存じでしょうか

こちらの受験ガイドからサンプル問題を確認することが可能です

https://quip.com/dyBMAO1z6pJ9/SALESFORCE-

https://tandc.salesforce.com/credentials

今回は
Salesforce上級アドミニストレーター試験の公式サンプル問題1問目をご紹介します

なお、
以下の問題は、Salesforce 認定上級アドミニストレーター試験のサンプル問題です。問題はあく まで出題形式に慣れていただくためのものであり、試験に合格するかどうかを判断するための問題ではありません。実際の問題の難易度は、以下のサンプル問題とは異なる場合があります。

と書いてありますのでご確認ください



問題はこちらです

1)
ユニバーサルコンテナ社では、取引先責任者レコードに「給与」カスタム項目があり、シス テム管理者を除いてすべてのプロファイルに対して表示されていません。システム管理者 が、採用担当者とアシスタントに給与項目の「参照のみ」アクセス権を与えるように依頼されました。採用担当者とアシスタントには、現在2つの異なるプロファイルが設定されています。 

システム管理者がこの要件を満たすにはどうすればよいでしょうか？ 答えを 2 つ選んでください。 

A.  採用担当者とアシスタントの「給与」項目に対するアクセスレベルを「参照のみ」に 変更する 
B.  給与項目の条件に基づく共有ルールを使用して、取引先責任者オブジェクトの 共有ルールを作成する 
C.  給与項目に「参照のみ」アクセス権を設定した権限セットを作成して、アシスタントと 採用担当者のユーザに割り当てる 
D.  アシスタントと採用担当者の新しいプロファイルを作成して、これらのユーザを新しい プロファイルに再割り当てする

![問題01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/b2fb848a-3c6e-d90f-81d4-a76cd8daf867.png)




正解はAとＣです

問題の解説にはいります

今回の内容は
・取引先責任者にカスタム項目給与があり現在はシステム管理者を除いてすべてのプ  ロファイルに対して表示されていません
・採用担当者とアシスタント　というプロファイルがそれぞれ存在する
・採用担当者とアシスタント　に給与項目を参照にしたい
ということですね

１つのアプローチとしてプロファイルごとの項目設定の変更です

A.  採用担当者とアシスタントの「給与」項目に対するアクセスレベルを「参照のみ」に 変更する 


もう１つはユーザそれぞれに権限セットを割り当てることですね
C.  給与項目に「参照のみ」アクセス権を設定した権限セットを作成して、アシスタントと 採用担当者のユーザに割り当てる 


こちらの設定により項目設定が可能です
プロになるWeb技術入門を読んだ

読んだ感想：とても実践的でわかりやすい内容でした。古い本だから今でも通用するか心配していたが全く問題なくむしろ今まで読んだ技術書でトップレベルに読んでよかったと感じました。

例えばこんなことを学べますということをまとめます。

#### リクエストとは
Webサーバーに何かを要求することであり、レスポンスとはそれに対するサーバーからの返答である。

#### ステートフルとは
状態を持っていることである。反対にステートレスとは状態を持っていないことである。とりわけプロになるWeb技術入門では通信を例にこれらが説明されていた。例えばFTP通信は通信を開始してから、切断するまでお互いが繋がった状態である。明示的に通信を開始する、切断するとお互いに交信する必要がある。一方でHTTP通信は1回のリクエストに対して1回のレスポンスのみがあり、それ以降はお互いのブラウザとサーバーは通信状態ではなくなる。これは本に書いていないが、電話の同期通信とメールの非同期通信のようなものだ。

#### プロトコルとは

通信の約束ごとである。私たち日本人がコミュニケーションを取る時は日本語で話すという暗黙の約束事がある。タガログ語で話されても何を言っているかわからないだろう。同じようにコンピュータ同士が通信するにはお互いが同じコミュニケーションツールで通信するという約束をする必要がある。具体例としてはファイルの通信をするにはFTPを使い、HTMLを送るにはHTTPを使おうという約束事である。この約束事がお互いでズレていると、お互いが何を言っているかわからない状態になる。そして、ポート番号とは、このHTTPやFTPを番号で表したものである。例えばHTTPは80でFTPは20,21である。逆に言うと80や20,21という数字からHTTPやFTPを識別できる。
代表的なものは他にも 25SMTP
53DNS
110POP3
443HTTPS
などがある。

#### Cookieとは
ステートレスであるHTTP通信において通信をまるでステートフルのように持続的に通信しているかのように使えるようにしたものである。この技術によってログイン処理やおすすめ機能が出来るようになった。具体的には、例えばメールアドレスとパスワードのログイン処理では1度目の通信ではブラウザからサーバーにリクエストする時にリクエストボディにメールアドレスとパスワードを入れておくと、レスポンスではそのメールアドレスとパスワードのセットまたはそのセットだと識別できるセッションIDを返す。ログイン完了後、どこかのページを見るためのリクエストでは、リクエストボディにCookieを一緒に入れてリクエストする。こうすることでログイン済みのユーザーがページを見たいとリクエストしてきたと判別できる。
1GBのファイルを作成する

# はじめに

1GBのファイルを作る方法です。

# Windowsの場合

コマンドプロンプトでfsutilというコマンドを実行します。

```bat:
fsutil file createnew 1gb.gomi 1073741824
```
なかなか見ないぴったり1GBのファイル。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/9308278c-8bb6-5c31-c4e4-b7d17a55a0e7.png)

```python:1 GBとは
1 GB = 1,024 MB 
     = 1,024 * 1,024 KB 
     = 1,024 * 1,024 * 1,024 B 
     = 1,073,741,824 B
```

# Linuxの場合

ddコマンドで作成します。

```bash:
dd if=/dev/zero of=1gb.gomi bs=1M count=1024
```

# おわりに

時々ほしくなる大容量のファイルですが、作成する際にはディスクの空き容量に注意しましょう。

# 参考文献

https://atmarkit.itmedia.co.jp/ait/articles/0209/28/news002.html

https://qiita.com/toshihirock/items/6cb99a85d86f524bc153
ズンドコキヨシ on Easy-ISLisp パターンマッチング

# はじめに
しばらく前にズンドコキヨシというのが流行っていたみたいです。これはElixirライブラリのdefpattern をテストするのにうってつけです。試してみることにしました。改良しましたので最新版をお使いください。

# コード
こんな風になります。とても簡潔に記述することが可能なことが確認できました。

```lisp
#|
ズンドコキヨシ

(gen-zundoko n) generate list length n. Each element is "ズン" or "ドコ"
(zundoko ls) ls is above list. If find pattern "ズン" "ズン" "ズン" "ズン" "ドコ"　
　　　　　　　return "キ☆ヨ☆シ！"
|#
(import "elixir")

(defun gen-zundoko (n)
    (cond ((= n 0) nil)
          ((= (random 2) 1) (cons "ズン" (gen-zundoko (- n 1))))
          (t (cons "ドコ" (gen-zundoko (- n 1))))))


(defpattern zundoko 
    ((empty-list) nil)
    ((("ズン" "ズン" "ズン" "ズン" "ドコ" :rest _x)) 
     (format (standard-output) "ズン ズン ズン ズン ドコ キ☆ヨ☆シ！"))
    (((_x :rest _y))
     (format (standard-output) "~A " _x) (zundoko _y)))

> (zundoko (gen-zundoko 30))
ズン ドコ ズン ズン ズン ドコ ドコ ドコ ズン ドコ ズン ドコ ズン ドコ ズン ドコ ズン ズン ズン ズン ドコ キ☆ヨ☆シ！NIL

```

# パターンマッチングの利点
普通にLispで書くと caddr cadddr caddddr とか煩雑になりがちです。defpattern マクロを使えばすっきりすることが確認できました。

# Lisp処理系とコード
ここにおいてあります。OSSです。ご自由にライセンスの範囲内でお使いください。

https://github.com/sasagawa888/eisl
直前に誤ってコミットした時の対処法

# はじめに
**直前に**誤ってコミットしてしまった時の対処法をまとめました。

# 背景
本来ならAというブランチで作業しないといけない所、Bというブランチで作業してコミットをしてしまいました・・・。
そのため、直前にコミットしてしまったログを取り消したいと思い、調べて実行した結果を以下にまとめています。

:::note warn
リモートリポジトリにpushしていない場合にのみ、以下のコマンドを使用してください。
:::

# gitコマンド
```shell:ターミナル
$ git reset --hard HEAD^
```

上記のコマンドを、該当リポジトリの誤ってコミットしたブランチ上で入力すると、**直前のコミットを取り消すことができます。**
実際に、以下のコマンドを入力して、コミットのログを確認してみましょう。

```shell:ターミナル
$ git log
```

## 実行前
![スクリーンショット 2022-10-16 8.44.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2849898/2ea78c8f-d6e1-b59f-4ddd-a45df31004e6.png)


## 実行後
![スクリーンショット 2022-10-16 8.46.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2849898/2b00f652-05bf-97ee-7389-bf5ccafc162b.png)


実際に、コミットしたログを取り消すことができていると思います。
このように、直前のコミットを取り消すことができます。

:::note alert
コミットのログだけでなく、修正したコードも消えてしまうため、実行には注意しましょう。
:::

# おわりに
gitは仮にミスをしたとしても、取り返すことができます。
なので、落ち着いて、調べたことを実行してみましょう。

記事をご覧いただき、ありがとうございました。
お家サーバー その6

# 概要
お家サーバーやってみる。
wordpressやってみた。

# インストール

wget https://ja.wordpress.org/latest-ja.tar.gz

tar -xzvf latest-ja.tar.gz

sudo mv wordpress /var/www/html

# 設定

ブラウザで、https://***.f5.si/wordpressを開く。
データベースを設定する。
コピペして、wp-config.phpを設置する。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/997efe1e-2bda-ca5a-b14a-5a7049775c1e.png)


以上。
お家サーバー その5

# 概要
お家サーバーやってみる。
mysqlサーバーが壊れた。

# 症状
mysqlが繋がらない。
ログにInnoDB: Error:が出てる。

# 初期化の手順

# 削除
sudo rm -r /var/lib/mysql/*

# 新しく作る
sudo mysql_install_db --user=mysql

# 起動
sudo systemctl start mysql

# databaseを作る。

sudo mysql
create database mydb;
create user 'yamada'@'localhost' identified by 'tarou';
grant all on mydb.* to 'yamada'@'localhost';

以上。
MAMPでPHPのバージョンが古いと怒られた場合の対処方法

自分の環境　⇨　Mac　＋　MAMP


【表題の件についての解決方法】

下記、参考になるサイトに従い、PHPのバージョンを7.4.21(2022/10/16現在選べるMAMP上のPHPのバージョン）と指定する。

[参考]https://gray-code.com/php/specify-php-version-in-composer/



【具体的説明】

Laravel-simple-memo(Laravelプロジェクト)直下にcomposer.jsonファイルがある。

当該ファイルを書き換えて、設定を変更することでエラーを解消する。



以下、composer.jsonの変更箇所になります。

```json:composer.json
"config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true,
        "platform": {
            "php": "7.4.21"
        }

```
変更後、保存した上でコマンド「composer update」を実行。

（※実行場所はLaravel-simple-memoで行う。）



【まとめ】

エラーの内容を要約すると、PHPのバージョンが古いと言われていた。（8.10以上が必要）

本件を解決するには以下案を考えてみました。

１）PHPのバージョンを7.4.21以上に変更する。（PHP7系を使いたい為、こちら採用）

２）ComposerでPHPのバージョンを指定する。

しかし、MAMPで使えるPHPのバージョンが8.0.8になるので、本件解決するには２）となると考え、上記を解決方法を実行しました。
ソース管理からGit操作ができないときは

# はじめに

Windows 10からWindows 11にアップグレードしようとするも10回くらい失敗したのでクリーンインストールしました。
それにともなってVSCodeやらGitをインストールしました。

なんと以前のワークスペースをVSCodeで開くと、`ソース管理`に「リポジトリを初期化する」というボタンが表示されているではありませんか。
ターミナルからgitコマンドは呼べるからインストールは問題ないようだし、VSCodeの設定で直接git.exeの実行ファイルのパスを指定しても変わらないのはなぜなんでしょう？

# VSCodeがGitリポジトリを認識しなくなった！

その原因はGitのバージョンアップによるものかもしれません。

どうやら[Git 2.30.3](https://github.com/git/git/blob/master/Documentation/RelNotes/2.30.3.txt)に[CVE-2022-24765](https://github.blog/2022-04-12-git-security-vulnerability-announced/)という問題に対応する変更が加えられ、[Git 2.35.2](https://github.com/git/git/blob/master/Documentation/RelNotes/2.35.2.txt)以降のバージョンで適用されているようです。

ターミナルで`git status`と実行すると

```
fatal: detected dubious ownership in repository at 'path/to/repository'
'path/to/repository' is owned by:
        'owner-user-id'
but the current user is:
        'current-user-id'
To add an exception for this directory, call:

        git config --global --add safe.directory path/to/repository
```

と表示されました。
指示通り

```
git config --global --add safe.directory path/to/repository
```

を実行して、ワークスペースを読み込みなおすとうまくいきます。

# その他

上記の方法はVSCodeでワークスペースを信頼するように、Gitのconfigに信頼するディレクトリを追加するものです。
追加したディレクトリ一覧を確認したり編集したりする場合は

```
git config --global -e
```

でconfigを編集するといいでしょう。

configに値を書き込みたくない場合、

```
takeown /r /s pcname /u username /f path/to/repository
```

と実行して所有者を変え、警告を回避する方法もあるようです。

# 参照

https://www.nda.co.jp/memo/git_safe_directory

https://zenn.dev/kouta/scraps/726bfce243f72b
Kubernetesのclass達

## こいつら何？

StorageClass, ingressClass

CKAの勉強やハンズオンやってると、各種classはとりあえず指定した値を書いといてみたいな扱いになりがち（多分）なんですが、classって名前なんだから重要なんだろうと思って調べました。


## 一般的なclassとは。

classとはプログラミングにおいては普遍的なパラダイムで、特定の目的に即したデータの構造とそれらを利用する振る舞い（関数、メソッド）を持つオブジェクトの設計書です。
以下wikipediaのクラス（コンピュータ）の前文記載します。


>[Wikipedia: クラス (コンピュータ)](https://ja.wikipedia.org/wiki/クラス_(コンピュータ))より
>オブジェクト指向プログラミングにおけるクラス（英: class）[1]は、オブジェクトを生成するための設計図あるいはひな形に相当するものである。抽象データ型の一つ。クラスから生成したオブジェクトの実体のことをインスタンスという。
クラスには、クラス自身またはクラスのインスタンスが保持するデータと、データに関連したオブジェクトの振る舞いを記述できる。プログラミング言語によっては、それぞれにアクセス修飾子（英語版）を指定できる。統一モデリング言語 (UML) のクラス図では、データのことを「属性」、振る舞いのことを「操作」と呼ぶ。Javaなどでは、データのことを「フィールド」、振る舞いのことを「メソッド」と呼ぶ。C++などでは、データのことを「メンバー変数」、振る舞いのことを「メンバー関数」と呼ぶ。






---

## Kubernetesにおけるclass

Kubernetesにおけるclassはデータ構造体のみの役割となり、振る舞いはSchedulerやcontrollerなどがそれを読み取って実行する。

## KubernetesAPIにおけるclass

KubernetesAPIには以下記載

|名前|apiVersion|役割|
|:--------|:-------|:----------|
|[PriorityClass](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/priority-class-v1/)|scheduling.k8s.io/v1|プライオリティクラスはPodのスケジューリングする際の重みづけを整数で行うためのクラスです。PriorityClass.metadata.nameを使って、優先度を区分ごとにネーミングをして優先度を設定する可能です。重みはpod.spec.priorityにスケジュールの際に設定されます。|
|[IngressClass](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-class-v1/)|networking.k8s.io/v1|IngressClassは特定のIngressControllerをIngressに紐づけるためのclassです。この名前を変えるだけで各ベンダのマネージドサービスのIngressControllerや独自のそれと切り替えることができます。|
|[StorageClass](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/storage-class-v1/)|storage.k8s.io/v1|StorageClassは、PersistentVolumesを動的にプロビジョニングできるストレージクラスのパラメータを記述します。StorageClassesは名前空間化されていない。etcdによるストレージクラスの名前はObjectMeta.Nameにあります。|
|[RuntimeClass](https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/runtime-class-v1/)|node.k8s.io/v1|OCIを設定するためのClass。runc以外にもmicroVMを使ったkataやgolangで書かれたシステムコールを行うgVisoryのようにpod以外に加えたリソースを消費するOCI向けにリソース割り当てを定義することができる。|

## 結論

みんな大事、おしまい。
Githubにpushした際に自動でJenkinsでgit pullを行う

やっとJenkinsを導入しました。CI/CDをどんどん進めるぞ！

ってことで、ローカル開発が完成してGithubにpushしたタイミングで自動でテスト環境でgit pullをするように設定を行いました。

結構手こずったのでメモしておきます。

# 全体構成図
今回実現しようとした環境の全体像はこんな感じ。
![スクリーンショット 2022-10-15 14.25.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1926542/8945a436-eb05-bf89-e36c-7679b2c0e664.png)

1. ローカル環境でgit commit後、git pushでGitHubにアップロード
1. GitHub Actionを利用してテストサーバ上のJenkinsのジョブをAPI経由で起動
1. Jenkinsのジョブの中でpullと同時にユニットテスト、composer updateやnpm buildを実行

# Jenkinsのインストール
Jenkinsのインストールは以下を参考に行いました。
何も問題なくインストールが完了し、Jenkinsが起動

https://linuxize.com/post/how-to-install-jenkins-on-debian-10/

# GitHubへのアカウント登録とリポジトリ作成
既にアカウント登録とリポジトリ作成は完了していたので今回は省略

# JenkinsでGitHub情報の設定とジョブの登録
以下のページを参考にJenkinsのジョブを登録。

https://sil.hatenablog.com/entry/jenkins-github-auto-deploy

:::note warn
GitHubのリポジトリを設定しようとすると'jenkins host key verification failed'が起こってしまいました。原因はknown_hostsファイルにgithub.comの情報が書き込まれていないことが原因のようです。いくつか対応策はあるみたいですが、私は以下の方法で対応しました。
:::

1. 「Jenkinsの管理」＞「グローバルセキュリティの設定」をクリック
1. 画面の一番下までスクロールし、「Git Host Key Verification Configuration」の「Host Key Verification Strategy」で「Accept First Connection」を設定

ビルドスクリプトとしてJenkins画面で直接スクリプトを記述するとgit pullの際に.git/index.lockファイル作成時にPermissionエラーが出たのでスクリプトファイルをテストサーバ上において、Jenkinsの画面ではそのファイルを起動するコマンドだけ記載しました。

# GitHubとJenkinsのWebhook連携
これが結構手こずりました。ネットで検索すると多くの方がやり方を投稿してくれているのですが、それぞれ設定方法が微妙に異なり、色々と試しましたがなかなかうまくいかず。。。

最終的には検索した時点で一番最新記事だった以下のページを参考にしたところやっとうまく行きました。

https://learn.microsoft.com/ja-jp/azure/developer/jenkins/deploy-from-github-to-aks

注意すべきポイントは以下かと思います。

* JenkinsのGitプラグインを使用(私の場合、インストール時点で入っていました）
* Jenkins側のビルドトリガには「GitHub hook trigger for GITscm polling」を利用
* GitHub上で「Integrations & services」という項目はないので「Webhook」から設定
* PayloadURLには[jenkinsのURL]/github-webhook/を記述(最後の/を忘れないように)

これでやっとやりたいことが全てうまくできるようになりました👍
Perlのリファレンス -  テキスト処理プログラミング入門【Windows・Mac・Linux対応】

Perlのリファレンスについて解説しました。

https://www.youtube.com/watch?v=gWUYOqrsCnQ

・リファレンスとは
・リファレンスの作り方
・スカラのリファレンス、配列のリファレンス、ハッシュのリファレンス
・サブルーチンの引数にリファレンスを渡す
・多次元データ構造はリファレンスがないと作れない
・配列のリファレンスとハッシュのリファレンスを簡単に作る方法
・Perlのソースコードを読むときは、かっこの違いをしっかりみる

リファレンスと多次元データ構造 - Perlゼミ

https://perlzemi.com/blog/20100930127859.html

■Perlプログラミングちゃんねるとは

Perlプログラミングちゃんねるは、初級者向けのPerlプログラミング入門講座です。テキスト処理プログラミングを覚えると文章の中に含まれる文字を簡単に検索・置換できるようになります。対応OSは、Windows/Mac/Linuxです。

テキスト処理プログラミングは、一番簡単なプログラミングの分野のひとつです。プログラミングが初めての方でも大丈夫。

Perlのダウンロードとインストールからはじめて、Perlの基本的なプログラミングが書けるようになります。Perlゼミの無料オンラインテキストも活用できます。わからないことがあれば、Perlクラブフォーラムで、質問することができます。
VPCフローログを作成にする

# CloudWatchのロググループを作成する
AWSマネジメントコンソールにログインしてください。
CloudWatchのダッシュボードを表示してください。

左メニューの[ログ]-[ロググループ]をクリックしてください。
![スクリーンショット 2022-10-16 5.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/cecd4264-e84d-5df9-fe0e-04dbc1f4a361.png)

ロググループのページが表示されます。
[ロググループを作成]をクリックしてください。
![スクリーンショット 2022-10-16 5.54.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/1f26a63d-a5ed-78fd-c767-6c2bb34647b5.png)

ロググループを作成ページが表示されます。
[ロググループ名]にお好きな名前を入力し、[作成]をクリックしてください。
![スクリーンショット 2022-10-16 5.52.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/ab639629-e359-32f2-3b71-1581b797ff07.png)

# IAMロールを作成する
VPCフローログからCloudWatchにアクセスするためのIAMロールを作成します。
IAMダッシュボードを表示してください。
左メニューの[ポリシー]をクリックしてください。
![スクリーンショット 2022-10-16 6.03.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/1218d5e5-fda4-e638-42d2-ae1b2e290de7.png)

ポリシーページが表示されます。
[ポリシーを作成]をクリックしてください。
![スクリーンショット 2022-10-16 6.04.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/34fe5277-1b39-a99e-059f-cca05d236573.png)

ポリシーの作成ページが表示されます。
[JSON]をクリックしてください。
以下を入力してください。
[次のステップ:タグ]をクリックしてください。
```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogGroups",
        "logs:DescribeLogStreams"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
} 
```

タグを追加ページが表示されます。
[次のステップ:確認]をクリックしてください。

ポリシーの確認ページが表示されます。
[名前]に「FlowlogsRole」と入力し、[ポリシーの作成]をクリックしてください。

左メニューの[ロール]をクリックしてください。
ロールページが表示されます。
[ロールを作成]をクリックしてください。
![スクリーンショット 2022-10-16 6.12.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/a9a1e9ca-0682-7903-dd7a-86386623bd4e.png)

信頼されたエンティティを選択ページが表示されます。
[信頼されたエンティティタイプ]で、「AWSのサービス」を選択してください。
[ユースケース]で、「EC2」を選択してください。
[次へ]をクリックしてください。

許可を追加ページが表示されます。
先ほど作成したポリシー「FLowlogsRole」を選択し、[次へ]をクリックしてください。

名前、確認、および作成ページが表示されます。
[ロール名]に、「Flowlogs-Role」と入力し、[ロールを作成]をクリックしてください。
![スクリーンショット 2022-10-16 6.17.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/0960d835-6f46-7041-4daa-c11a3924fca7.png)

# VPCフローログを作成する
VPCのダッシュボードを表示してください。
[VPC]をクリックしてください。
![スクリーンショット 2022-10-16 5.55.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/6d46f0ad-379d-cc7c-658b-80e0b978c04c.png)

VPCフローログを作成するVPCをチェックし、[アクション]-[フローログを作成]をクリックしてください。
![スクリーンショット 2022-10-16 5.57.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/8ec3f9b9-9a2b-7b69-bbec-7dc2d4bdae1c.png)

フローログを作成ページが表示されます。
[名前]に好きな名前を入力してください。
![スクリーンショット 2022-10-16 6.20.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/c001bdff-44b9-e2c4-6f25-94792279504a.png)

[送信先ロググループ]に、先ほど作成したCloudWatchのロググループを選択してください。
同様に、[IAMロール]に、先ほど作成したIAMロールを選択してください。
![スクリーンショット 2022-10-16 6.20.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/99fcf6cc-9265-ae89-6b8e-4d8fee2f4da1.png)

[フローログを作成]をクリックしてください。

以上です。
ApacheのアクセスログをApacheLogViewerで統計的に分析する

## やりたいこと
AWSのCloudWatchやZabbix等の監視系ツールで、CPUやメモリ使用率が一時的にスパイクすることがある。
原因は一時的な、アクセス数が増えた場合もあるが、今日において、攻撃を受けている場合も多い。
その際の私なりの、Apacheアクセスログの分析方法を記載したいと思います。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879925/49a455f5-4d66-a10b-7dd3-d57762e88747.png)
## 前提条件
- WebサーバがApacheであること。
- Webサーバ内の/var/log/httpd/access.logのファイルを自分の取得しておく。
※ファイルが肥大化していると、ダウンロードが大変になるので、適切なログローテートが行われていること。
- ApacheLogViewerをダウンロードしておくこと(https://www.vector.co.jp/soft/dl/win95/net/se252609.html)。
エクセル等で、フィルタして分析することもできるが、こちらであれば自動的にグラフ等を作ってくれるため、分析がしやすい。

## アクセスログをApacheLogViewerで分析する
- ApacheLogViewer(以下exe)を開き画面左上の「…」ボタンをクリックし、分析したいアクセスログファイルを選択する。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879925/f5c2e775-bdbd-d3dd-32f4-e91ea7d36eb2.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879925/214d42c0-8904-730f-7089-a41ae09f0f5c.png)


- アクセスログが表示されるので、この時点でざっと確認し、**<font color="Red">赤字が連続している箇所がないか探す。</font>**
※監視ツールで折れ線グラフが一番跳ね上がっていた時間帯で確認する。
※基本的に404エラーでCPU使用率が跳ね上がることが多い。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879925/627f2d86-02ce-5745-5d2a-ee0c6ea9934c.png)

- 赤字(エラーログ)内で以下がないか確認する
  - Request欄のURLが実際には存在しないURL
  - Agent欄のユーザーエージェント(どのブラウザ・OSでアクセスしているか)に共通しているのがあるか。
※Mozilla等から始まるものは普通のブラウザであることが多い。
※以下URLに、ユーザーエージェントを貼り付けることで、ブラウザ・OSの確認が可能。
http://mobile.shinsv.mydns.jp/useragent_check/
  - 同じユーザーエージェントが大量に連続していないか。

## 詳細に分析する場合
アクセスログが大きい場合、赤い行の共通性等が分からない場合は、統計分析を行う。
- 画面左下Statisticsボタンをクリックする。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879925/49783199-586a-36dd-e9a4-9574e4e2f09d.png)
- 上のタブ内でErrorを選択し、下のタブ内で日時・ユーザーエージェント、での集計結果を確認する。
※個人的にはRequest、Userの順で確認すると良い。
※以下画像は例として、脆弱性診断ツールのOpenVASによる攻撃のパターンです。
※画像内のログは手動で作成したもののため、実際に見るログは違うものになります。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879925/35348e42-de30-b0f8-930c-4460040747a7.png)

##備考
AWSでロードバランサ経由でアクセスがされている場合は、Host欄のIPがロードバランサのIPになってしまうためアクセス元の分析ができません。ユーザーエージェントも偽造ができるらしいので、例えばアンドロイドかつクローム経由だった場合は、スマホで攻撃するとは考えられないので、偽造されていると考えられます。
もし、ApacheLogViewerがダウンロードできない現場の場合は、テキストエディタ等で、404がある行を色付けし、ざっと見るだけでも原因がわかる場合があります。
他の便利な分析方法等をご存じの方は是非教えて下さい。
キャリアアップやキャリアチェンジのために考慮したいトピック雑記

完全にチラシの裏です。ご参考までに。

## キャリアに関する一般的な事柄
* 待遇
* 役職
* 社格
* 企業文化

## キャリアアップ：ソフトウェア技術を扱うのか
### 対象領域
|対象領域|要素|
|---|---|
|アプリケーション|プラットフォーム（Front, Back, Mobile, Desktop, Embed, Game, Hard）<br>言語（PHP, Ruby, Python, Java, C#, Go, JavaScript, Kotlin, Swift, C++, Rust）|
|インフラ・ミドルウェア|データベース、クラウド、ネットワーク/Web、システム（OS）|
|サイエンス|アルゴリズム・数値計算・データエンジニアリング・機械学習|
### 学術的な基礎づけ
|大項目|小項目|
|---|---|
|計算機科学|コンピュータアーキテクチャ、理論計算機科学<br>数理論理学、データ構造とアルゴリズム、…|
|ソフトウェア工学|要求工学、アーキテクチャ・設計<br>セキュリティ、DevOps、ソフトウェアテスト、…|

## 事業形態
|観点|バラエティ|
|---|---|
|フェーズ|プロトタイプ ―― 新規開発 ―― 運用|
|開発体制|リーン / アジャイル / ウォーターフォール |
|ビジネスドメイン|エンタープライズ系 ――――― Web系|
|ビジネスモデル|SaaS / 売り切り / 広告, B2C / B2B / B2B2C|


## キャリアチェンジ：関連職種は何があるのか
### 技術職
* セールスエンジニア
* サポートエンジニア
* 情シス（IT）

### 他職種を見つけるための関連領域
```plantuml
skinparam rectangle<<behavior>> {
	roundCorner 25
}
sprite $bProcess jar:archimate/business-process
sprite $aService jar:archimate/application-service
sprite $aComponent jar:archimate/application-component

rectangle "経営・ストラテジ" as strategy #Strategy
rectangle "ソフトウェア・システム" as system #Technology
rectangle "サービス・プロダクト" as service #Application
rectangle "プロジェクト" as project #Business
system -up- service
system -down- project
strategy -up- service
strategy -down- project
strategy -right- system

rectangle "アプリケーション" as application #Technology
rectangle "インフラ・ミドルウェア" as infrastructure #Technology
rectangle "サイエンス" as science #Technology
system -up- infrastructure
system -right- application
system -down- science
application -up- infrastructure #transparent
application -down- science #transparent

rectangle "サービス運用" as operation #Application
rectangle "デザイン" as design #Application
rectangle "マーケティング" as marketing #Application
service -up- operation
service -up- design
service -up- marketing

rectangle "リソース管理" as resource #Business
rectangle "ディレクション" as direction #Business
rectangle "HR" as people #Business
project -down- resource
project -down- direction
project -down- people
```
Enumを使って複数の定数文字列を管理する。

## 2022/11/11 追記

`StrEnum`がPython11で実装されたのでそれも使いましょう。

[Official Docs](https://docs.python.org/ja/dev/library/enum.html#enum.StrEnum)

# Enumは複数の定数をクラスに纏めて管理できる

```python
import enum

class Option(enum.Enum):
    A = "A"
    B = "B"
    C = "C"

my_choice = Option.A
print(my_choice)
# <Option.A: 'A'>
```

このように定義すると、`Option.A`のように定数を呼び出すことができ`Literal`と違いタイプミスや、定数の値を間違えてもエラーとして検出できる。

## Enumは文字列と比較できない

```python
my_choice = Option.A
print(my_choice == "A")
# False
```

EnumはEnum.Valuesのインスタンスなので、文字列と比較するとFalseになる。

## 解決策

クラスを定義する際に`str`を継承することで文字列と比較できるようになる。

```python
import enum

class Option(str, enum.Enum):
    A = "A"
    B = "B"
    C = "C"

my_choice = Option.A
print(my_choice == "A")
# True
```
ソートアルゴリズム


1.今日のプログラミング
-----------
初めての投稿になるので、今日はソートアルゴリズムの中で一番簡単なバブルソートでも書いていこうかなと思います。

2.ソートアルゴリズムとは
-----------
そもそも、ソートアルゴリズムって何それ。。って思う人も中にはいると思います。
なので、ソートアルゴリズムについて少し説明しようと思います。

-----------
ソートアルゴリズムの「ソート」とは整理、並び替える。という意味があります。
小さい実装が多い自分にはあまりなじみがないですが、もし、大量のデータを扱う機会が来たときそのデータがぐちゃぐちゃだったら誰も幸せになれないですよね？
その時に役に立つのがソートアルゴリズムです。

データを昇順、降順に**並べ替え**たり、一定の規則に倣（なら）って**整理**したほうが、みんな幸せになりますよね？

なので、あんまり自信ないな、、と思う人はぜひ一緒に幸せになりましょう。

3．バブルソート
---
バブルソートは隣接する値同士の比較をして、小さいほうを前へ、小さいほうを前へ、お前俺よりでかいやんけ。でかいやつはとりまそこに居て。または、俺のほうがでかいから前に行くぜー。小さいのはそのままそこに居な。
というのを繰り返し行い、大きい順または小さい順に並び替えます。

さあ書いていきましょう。

言語・・・C#
IDE・・・Visual Studio2022
※IDEとは、統合開発環境のことでテキストエディタ、コンパイル、デバッカーを一つにまとめてあるもののことを指す名称です。
Xcode,EclipseなどもIDEです。気になったら調べて見てください。

---
```cs:Algorithm.cs

static void Main(string[] args)
        {
            int[] bubbleSort = { 5, 7, 1, 4, 3, 6, 2 };
            SortAlgorithm(bubbleSort);
            for(var i = 0; i < bubbleSort.Length; i++)
            {
                Console.WriteLine(bubbleSort[i]);
            }
            //while (true) ;実行後すぐに画面が消えてしまう人は追加してみると改善します。
        }
        public static void SortAlgorithm(int[] array)
        {
            for(var secondMove = 0; secondMove < array.Length - 1; secondMove++)
            {
                for(var firstMove = 0; firstMove < array.Length - 1; firstMove++)
                {
                    if (array[firstMove] > array[firstMove + 1])
                    {
                    //ここの入れ替えが肝
                        var tmp = array[firstMove];
                        array[firstMove] = array[firstMove + 1];
                        array[firstMove + 1] = tmp;
                    }
                }
            }
        }
```
```cs:Algorithm.実行結果
1
2
3
4
5
6
7
```
このコードを実行すると小さい順に並びました。もし昇順にしたいのなら二重forのifの中の不等号を逆にしてみてください。

もっと簡単に実装する方法はありますが、自分はあえてこのように実装してみました。
なぜかというと、バブルソートで調べると山のように似たコードがあるからです。（悪いコードという意味ではないです。）
こんな書き方もあるんだというあたらしい発想の糧になてくれればと思います。

以上がバブルソートでした。

まとめ
---
初めての投稿なので足りてないんじゃない？、ここをこうしたほうが見やすい。コードが汚い。など思われるかもしれませんが、おいおい直していこうかなと思うのでコメントしてくれると嬉しいです。
今後もこんな感じでC#やUnityについてのことをやっていこうかなと思います。

・セレクトソート追加しときます　https://qiita.com/Ryosuke004682/items/2c3f4d8f55ed47ea20ed

参考資料 : [SortAlgorithm](https://products.sint.co.jp/topsic/blog/algorithm-type / ソートアルゴリズムにの図解が乗っててわかりやすいです。)
WindowsのC/C++からOpenCVのimread, imwriteを使うと日本語ファイルパスが通らない件の対応

#### Windows日本語ファイルパスの罠
WindowsのC/C++でOpenCVのimreadやimwriteで日本語ファイルパスにあるファイルを開こうとすると失敗します。C/C++に限らずPythonなどから呼び出しても起きるのですが、要するにUTF-8で書かれたファイルパスをWindowsのfopenで開けないのが原因です。
　
まことに残念ながら、OpenCV側ではこの問題は対処しないことに決めたようです。

https://github.com/opencv/opencv/issues/4292

上のエントリを見ると日本人のみならず、中国人は漢字が、韓国人はハングルが、ドイツ人はウムラウトがあと阿鼻叫喚ですが、最新のOSはWindowsを含めてだいたいUTF-8に対応してるはずだ、ダメなら一旦メモリに読み込んでからデコードしてちょ、ということらしい。えー、WindowsでUTF-8のパス通らないけどなー。

#### Windows C/C++ での対処
ダメならいったんメモリに読み込んでバッファをOpenCVてデコードせよとのことです。PythonではPython側で普通に読み込んでバッファを渡すという対処でいけるのですが、C/C++では普通に読み込んでがダメでした。C/C++ではUTF-8をwcharに変換して_wfopenを使う必要があるようです。

というわけでcv::imread、cv::imwriteの代替関数を書きました。UTF-8からwcharへの変換にはMultiByteToWideCharというWindows APIの関数を使いました。この関数はバッファサイズ0で呼ぶと変換後のバッファサイズを返すので、それでバッファを確保してあらためて変換を要請するという、面倒くさい仕様ですね。

* wimread()
・入力ファイルパスをUTF-8からwcharに変換する。
・wchar対応の_wfopen_sでオープンし、メモリ内にファイルを読み込む
・cv::imdecode()でMatに変換する

```C++:日本語パス対応imread(), imwrite()
Mat wimread(char* inpath) {
    setlocale(LC_ALL, "japanese");

    int size = ::MultiByteToWideChar(CP_UTF8, 0, inpath, -1, (wchar_t*)NULL, 0);
    wchar_t* winpath = (wchar_t*)new wchar_t[size];
    ::MultiByteToWideChar(CP_UTF8, 0, inpath, -1, winpath, size);

    FILE* fp;
    _wfopen_s(&fp, winpath, L"rb");
    delete[] winpath;

    if (fp == NULL) {
        std::cout << "cant open " << inpath << std::endl;
        return Mat();
    }

    long long int fsize = _filelengthi64(_fileno(fp));
    unsigned char* buff = new unsigned char[fsize];

    fread(buff, fsize, 1, fp);
    fclose(fp);

    // Matへ変換
    std::vector<uchar> jpeg(buff, buff + fsize);
    cv::Mat img = cv::imdecode(jpeg, 1);

    delete[] buff;

    return img;
}
```
* wimwrite
・入力ファイルパスをUTF-8からwcharに変換する。
・wchar対応の_wfopen_sでオープンする
・Mat内のデータをファイルに書き込む
・エンコードの品質95で決め打ちなので、必要ならなんとかしてください

```C++:日本語パス対応imread(), imwrite()
void wimwrite(char* outpath, Mat img) {
    setlocale(LC_ALL, "japanese");

    std::vector<uchar> buff2; //buffer for coding
    std::vector<int> param = std::vector<int>(2);
    param[0] = 1;
    param[1] = 95; //default(95) 0-100

    imencode(".jpg", img, buff2, param);

    int size = ::MultiByteToWideChar(CP_UTF8, 0, outpath, -1, (wchar_t*)NULL, 0);
    wchar_t* woutpath = (wchar_t*)new wchar_t[size];
    ::MultiByteToWideChar(CP_UTF8, 0, outpath, -1, woutpath, size);

    FILE* fp2;
    _wfopen_s(&fp2, woutpath, L"wb");
    delete[] woutpath;
    if (fp2 == NULL) {
        std::cout << "output cant open" << std::endl;
        return;
    }
    fwrite(buff2.data(), buff2.size(), 1, fp2);
    fclose(fp2);
}
```

同じことが、OpenCVの機械学習関連関数のモデルの読み込みでも起きます。そっちはファイルが大きいので、いったんメモリに取り込むとか無理だろうなあ。モデルを日本語ディレクトリに置かないようにすればなんとかはなりますが。OpenCVの中の人が言うWindowsでも最新リリースはUTF-8でfopenできるというのは何かやり方あるんだろか。
別プロセスのメモリを読みたかった話

# はじめに
ふとしたときになにかしらのプロセスのメモリを読みたくなることってあると思います。Windowsの場合`Win32API`で用意されている`ReadProcessMemory`を呼び出すことで動作中の別プロセスのメモリを読み取ることができます。これを使うことでいろいろできそう！と思ったのです。

# プログラムの概要

https://github.com/Mikage32/memoryReadProc-Sample

処理の流れを簡単にまとめると、
1. `CreateToolhelp32Snapshot`を用いて実行中のプロセス一覧のスナップショットを取得
2. `Process32First`と`Process32Next`でスナップショットからプロセスを一つずつ取り出せるので目的の名前のプロセスを探す
3. `OpenProcess`に目的のプロセスのProcessIDを渡してハンドラを取得
4. 取得したハンドラを`ReadProcessMemory`に渡してメモリ読み放題

と、なるはずでした。

# 問題点その１
いざ実行してみたところ`OpenProcess`でエラーを吐かれてしまいました。`GetLastError`を呼び出してエラーコードを見ると`0x5`の`ERROR_ACCESS_DENIED`とのこと。つまり権限がないということでした。調べるとデバッグ権限`SeDebugPrivilege`が有効でないといけないとのことなのですが、通常のユーザはそもそもデバッグ権限を持っていないので`AdjustTokenPrivileges`を呼び出しても権限の変更はできません。当然実行プロセスにもデバッグ権限を持たせることはできません。
仕方がないのでadminユーザで実行することでユーザの権限問題を解決。

# 問題点その2
ユーザ権限問題が解決したことでとりあえず`chrome.exe`などいくつかのプログラムは実行中プロセスのメモリを読み取ることができるようになりました。しかし、相変わらずいくつかのプロセスでは`OpenProcess`でアクセス拒否されてしまいました。結論を述べてしまうと、外部プロセスからのアクセスを許可しない設定で立てられたプロセスにはアクセスできないということでした。例えばWindowsのシステムプロセスなどは常にアクセスを拒否されます。また、プロセスを立てる際に`BuildExplicitAccessWithNameA`を呼び出して`ACE:Access Control Entry`を設定することで外部プロセスからのアクセスを拒否できるようになります。

# 最後に
思ったようにいかなくて残念な一方、アクセスの拒否設定ができなければいくらでも悪いことができてしまうことになるので考えてみれば当然の話でした。もっとも、`Win32API`を使ったお手軽なやり方ではだめだったというだけなので「どうしてもメモリが読みたい！」という人は他の手段をとればいくらかやりようはあると思います。くれぐれも悪いことはしないようにされないように気を付けていきたいものですね。

# 参考ページ
http://popopondelion.blog.fc2.com/blog-entry-18.html

https://riosu.hateblo.jp/entry/2013/09/06/001208

http://eternalwindows.jp/security/accesscontrol/accesscontrol13.html
EC2×2台S3なし環境にて、/wp-content/uploadsディレクトリの内容を一方向同期する

## やりたいこと
AWSでWordPressのEC2サーバ2台の冗長構成を構築したとする。
同期元サーバでWordPressのuploadsフォルダの中身に変更があった際に、自動的に同期先サーバにコピー/削除/更新がされるようにしたい。
![WP同期.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879925/cbc46667-25fb-9f48-88dd-21e4fac3d3db.png)


## 前提条件
- セキュリティグループにてサーバ間のSSH(22),rsync(873)の通信ができるようにされていること
- 同期先のsshd_configにて、同期元IPからのroot接続を許可しておくこと
```:/etc/ssh/sshd_config
#WordPress rsync
Match User root
    AuthenticationMethods publickey
Match Address 同期する側のIP
    PermitRootLogin yes
```
※上記設定後sshdサービスを再起動、同期元から同期先にrootでのssh鍵認証ができるようにしておくこと

## 同期元に必要なコマンドをインストール
```

$ sudo amazon-linux-extras install epel -y
$ sudo yum --enablerepo=epel install rsync lsyncd

```
## 同期元の/etc/lsyncd.confを編集
```:/etc/lsyncd.conf
settings{
    logfile = "/var/log/lsyncd.log",
    statusFile = "/tmp/lsyncd.stat",
    insist = 1
}

sync{
  default.rsync,
  source = "/var/www/html/wp-content/uploads",
  target = "root@同期される側のIP:/var/www/html/wp-content/uploads",
  rsync = {
    archive = true,
    update = true,
    rsh="/usr/bin/ssh -i/root/.ssh/id_rsa -o StrictHostKeyCheking=no"
  }
}

```
## 同期元にてlsyncdサービスを起動
```
$ systemctl start lsyncd.service
$ systemctl status lsyncd.service
```
## 同期元にてログが動いており、ファイルがコピーされていれば成功
```
$ tail -f /var/log/lsyncd/lsyncd.log
#上記ログを開いたまま、もう一つのSSH接続を行い、テストでファイルを作成してみる。
$ touch /var/www/html/wp-content/uploads/test.txt 
```
## 最後にlsyncdサービスが常時起動するように設定
```
$ systemctl enable lsyncd.service
```
以上
puppeteerのインストールエラー「Error: Cannot find module 'fs/promises'」


# インストールエラー

```
npm i puppeteer

> puppeteer@19.0.0 postinstall /home/k8uwall/tmp/pp/node_modules/puppeteer
> node install.js

(node:250405) UnhandledPromiseRejectionWarning: Error: Cannot find module 'fs/promises'
```

# 理由

nodejsが古いかららしい

https://stackoverflow.com/questions/68085375/cannot-find-module-fs-promises-electron-js

https://github.com/puppeteer/puppeteer
> Puppeteer follows the latest maintenance LTS version of Node.


# 対処

```
# dnf module remove --all nodejs
# dnf module reset nodejs
# dnf module install nodejs:16

$ npm i puppeteer

added 52 packages, and audited 53 packages in 29s

7 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice
npm notice New minor version of npm available! 8.11.0 -> 8.19.2
npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.19.2
npm notice Run npm install -g npm@8.19.2 to update!
npm notice
```