OmniAICreator/Qiita-1.07M huggingface dataset:
Google Cloud Professional Security Engineer受験記

先日、GoogleCloudの試験、[Professional Cloud Security Engineer Certification](https://cloud.google.com/certification/cloud-security-engineer?hl=ja)を初受験し合格したので、試験までの勉強方法などについてまとめます。


# 試験について

![pse.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345258/082d3188-c67c-5ed6-dd12-97d5de427c29.png)
Cloud Security Engineerは名前の通り、GoogleCloudにおいてセキュリティの高い設計と構築、運用を行うための能力を問われるものです。GoogleCloud全体におけるセキュリティを問われるもので、コンピュートリソースやネットワークといったシステム開発に直接かかわる部分だけでなく、CloudIdentityやWorkspaceなどについても広く出題されます。

受験可能言語は長らく英語のみでしたが、2022年3月から日本語での受験が可能になったようです。

# スキルセット
受験した私のスキルセットとしては以下の通りです。
 - GoogleCloud利用歴は4年程度
     - GKEをメインに、コンピュートリソースでのWebアプリケーション構築が主体
     - 業務にてネットワークやCICDの構築なども実施して、比較的広めにGoogleCloudサービスは触ってきた
 - GoogleCloud以外のクラウドサービスは経験無し
 - これまでに以下試験で合格
     - Google Associate Cloud Engineer
     - Professional Cloud Architect
     - Professional Data Engineer
     - Professional Cloud Developer

# 勉強の仕方

私の場合、どちらかというと「試験に合格することを主眼に置いた」勉強方法かもしれません。その点はご承知おきください。

1 模擬試験
何はなくとも、やはり模擬試験です。公式ページですと、[試験の概要] -> [学習プログラムを始める] -> [模擬試験]という進め方を提示していますが、私の場合まず問題を解いてみて合格までの距離感をつかむようにしています。
解いてみて明らかに何を言っているか分からないような具合だったら尚早かもしれません。私の場合、6割超くらい取れてこれなら大丈夫そうだと判断し受験を決めます。やや安全目にスケジュールを組み、だいたいここから1ヶ月以内くらいのタイミングでの受験としました。

ちなみに、模擬試験はその後も勉強を進めたのちに複数回解き直しをします。答えを適度に忘れたころにあらためて解いてみると効果があります。

2 試験ガイドの確認
模擬試験の具合からして合格目指せそうだと判断できたところから、ようやく学習内容を網羅的に把握します。それを先にやろうとすると多分飽きてしまう、という私の性格に合わせたやり方です。試験ガイドで意識するのは「知らない語や知らない機能が無いか」という点です。ガイドに載ってるすべての項目について具体的な設定方法なども覚えているかまで意識するとやや重たいので、広く浅くくらいで良いかなと思われます。

3 動画コンテンツでの学習
CouseraやQwiklabsなどを使った勉強方法も多く見受けられますが、机やPCに向き合って勉強するのが得意でない私は、動画を観て勉強するようにしています。Udemyで提供されている、ハンズオンの多い教材が私には合っていました。英語コンテンツですが、ハンズオンが多いこともありおそらくそこまで聞き取りは難しくないと思います。

4 試験ガイドの深堀り
全体を網羅出来たところであらためて試験ガイドを観返して、もう少し深くまで理解を深めます。各項目について、Udemyで勉強した箇所と理解がリンクしているか、設定画面やコマンドなどが思い浮かぶか、くらいのところまで確認します。もちろんその範囲外の項目もありますので、それらは都度公式ドキュメントを調べます。ここも、試験までに折を見て何度か確認するのが良さそうです。

# 実試験
リモート監視試験と実地試験がありますが、リモート監視の場合は環境を整えるのが大変と聞きますので私は実地試験にしました。

## 時間配分
私の場合は、やや早めに1周解ききりってから見直しで2周、合計3周するというのがこれまでの試験でも基本的なスタンスとしています。
1周目はだいたい1問40~50秒程度で、回答を保留したのも残しつつ50問最後までを40分程度で終えます。
50問あると同一サービスについて似たような問題が出ることもあるので、2周目はそれらとの整合性を確認しながら解き直します。
いったん50問解ききったから制限時間を怖がる必要もなくなり、見直しも焦ることなく出来ると感じています。
3周目の見直しで、結局最後まで分からない問題が残りますが、これはどうこうしても分からないものなので、おとなしく諦めます。
だいたい50分くらい残してここまで終わったので、そのまま試験終了しました。

# 所感
多分70%ちょっとくらいの出来だろうか？というイメージでの試験提出でした。若干不安はありましたが、無事に合格だったのでほっとしています。
冒頭で書いた通り、CloudIdentityやWorkspaceなどについての出題も多く、このあたりは勉強不足を感じました。実業務の中で触ることもなかったこともあり元々不安な箇所ではありましたが、上記の勉強法でも拾え切れていなかったなという反省があります。
他方、CloudKMSあたりはハンズオンを観るだけでもかなり情報が整理された感じがありました。

Professional資格がこれで4つ目となりました。引き続き別資格を取得するためにも、現在似たような方法で勉強を進めています。そちらも試験を終えたら同じように受験記を残したいと思います。
chownコマンド

# chownコマンドについて
・ファイルやディレクトの所有者を変更するコマンド、
・chownコマンドは管理者ユーザー権限で行われないと、権限なしで操作できない場合がある。chownコマンドは管理者権限のアカウントで操作する。

```
$ chown 所有者名 ファイル名またはディレクトリ名
```

変更コマンド
```
$ chown Noa config.dat
```

| オプション | 意味 |
| :--- | :---: | 
| -c | 変更があった場合に、メッセージを表示する| 
| -v |  コマンドの実行状況を表示| 
| -f |エラーメッセージを表示しない| 
| -h | シンボリックリンク自体の所有者を変更する| 
| -R | ディレクトリ内の所有者も変更する | 

※よく使うもの
```
$ chown -R 所有者名 ディレクトリ名
```
カレントディレクトリ配下のファイルやディレクトリの所有者をすべてFujiyaに変更するには次のコマンド.


参考サイト
https://eng-entrance.com/linux-command-chown
LANを構成する技術

# LANとは
社内や家庭内において、パソコンやサーバーをネットワーク（網目状）で繋ぎ、
相互にやりとりできるようにした仕組みを**LAN**(Local Area Network)という。ネットワークケーブルなどで有線で繋いだネットワークが**有線LAN**、無線で繋いだネットワークが**無線LAN**。

会社内で置かれたネットワークのことを**社内LAN**という。
会社によっては、社内LANがインターネットに接続していない場合がある
インターネットに接続していないネットワーク範囲をイントラネットという。

社内LANには、**ファイルサーバー**や**Webサーバー**、**システムを動かすサーバー**などが含まれていて、網目状に繋がっている。
最近は、こうした社内LANをAWSなどのクラウド上に移行する例が多い

## 無線LANとWi-fiの違い
「無線LAN」は無線通信で構築されたネットワークを指し、
「Wi-Fi」は無線通信の一規格を指します。



# LANを構成する技術
|項目|内容|
|-|-|
|ルーター|ネットワークの入り口になる部分に置かれる機器。片側から入ってきたデータの宛先を確認し、宛先に近いもう片方のネットワークにデータを転送する|
|HUB|ネットワークの配線を分割する装置。同一のネットワーク上の他の端末へとデータを転送する|
|FW|ファイアーウォール。出入りするデータを確認して、通して良いか判断する装置。不適切な場所からのアクセルを禁止したりするなど、セキュリティを高めるために用いる。|
|DMZ|非武装地帯。インターネットなどの外部ネットワークと社内ネットワークの間に設けるネットワーク。どちらからもアクセスできる|
|DHCP|接続された端末に自動的にIPアドレスを振る|
|サブネット|ひとつのネットワークをさらに小さくしたネットワーク|
Mono: C# で Json.NETの使い方

こちらのサンプルを動くプログラムにしました。
[Json.NET](https://www.newtonsoft.com/json)

## シリアライズ

```cs:serialize01.cs
// --------------------------------------------------------------------
/*
	serialize01.cs

						Aug/08/2022
*/
// --------------------------------------------------------------------
using	System;
using	System.IO;

using Newtonsoft.Json;
// --------------------------------------------------------------------
namespace JsonSample
{
class Product
    {
        public string Name { get; set; }
        public DateTime Expiry { get; set; }
        public string[] Sizes { get; set; }
    }



class	json_read
{
// --------------------------------------------------------------------
static	void	Main (string[] args)
{
	Console.WriteLine ("*** 開始 ***");

	Product product = new Product();
	product.Name = "Apple";
	product.Expiry = new DateTime(2008, 12, 28);
	product.Sizes = new string[] { "Small","Large" };

string str_json = JsonConvert.SerializeObject(product);

	Console.WriteLine (str_json);

	Console.WriteLine ("*** 終了 ***");
}

// --------------------------------------------------------------------
}

// --------------------------------------------------------------------
}
// --------------------------------------------------------------------
```

```text:Makefile
serialize01.exe: serialize01.cs
	mcs serialize01.cs -r:Newtonsoft.Json.dll
clean:
	rm -f *.exe
```

実行

```text
$ ./serialize01.exe 
*** 開始 ***
{"Name":"Apple","Expiry":"2008-12-28T00:00:00","Sizes":["Small","Large"]}
*** 終了 ***
```

## デシリアライズ

```cs:deserialize01.cs
// --------------------------------------------------------------------
/*
	deserialize01.cs

						Aug/08/2022
*/
// --------------------------------------------------------------------
using	System;
using	System.IO;

using Newtonsoft.Json;
// --------------------------------------------------------------------
namespace JsonSample
{
class Movie
    {
        public string Name { get; set; }

        public DateTime ReleaseDate { get; set; }

        public string[] Genres { get; set; }
    }



class	json_read
{
// --------------------------------------------------------------------
static	void	Main (string[] args)
{
	Console.WriteLine ("*** 開始 ***");

string json = @"{
  'Name': 'Bad Boys',
  'ReleaseDate': '1995-4-7T00:00:00',
  'Genres': [
    'Action',
    'Comedy'
  ]
}";


Movie m = JsonConvert.DeserializeObject<Movie>(json);

string name = m.Name;

Console.WriteLine(name);
Console.WriteLine(m.ReleaseDate);

foreach (string genre in m.Genres)
	{
	Console.WriteLine(genre);
	}

	Console.WriteLine ("*** 終了 ***");
}

// --------------------------------------------------------------------
}

// --------------------------------------------------------------------
}
// --------------------------------------------------------------------
```

```text:Makefile
deserialize01.exe: deserialize01.cs
	mcs deserialize01.cs -r:Newtonsoft.Json.dll
clean:
	rm -f *.exe
```

実行結果

```text
$ ./deserialize01.exe 
*** 開始 ***
Bad Boys
1995/04/07 0:00:00
Action
Comedy
*** 終了 ***
```

## Newtonsoft.Json.dll 

Json130r1.zip をダウンロードして解凍します。

Bin/net45/Newtonsoft.Json.dll を使います。
シンボリックリンクを張って使えます。
サーバーとインスタンス

# サーバーとは
AWSの代表的なサービスは、Amazon EC2(Elastic Compute Cloud)。
サーバーとは・・・**何かサービスを提供するもの**
ex)
* WebサーバーならWeb機能
* メールサーバーならメール機能
〇〇サーバーの機能は**ソフトウェア**によって提供される
サーバー機能を搭載するコンピュータ（＝物理的サーバーマシン）は一般的なパソコンと同様にOSが動いていて、その上でソフトウェアが動いている。
すなわち、物理的サーバーマシンに、Webサーバー用ソフトを入れればWeb機能を持つWebサーバーになる。また、メールサーバー用ソフトを入れればメールサーバーになる。
# サーバー１つに対して機能は複数入れられる
サーバー機能を搭載するコンピュータ（＝物理的サーバーマシン）に複数のソフトウェアをインストールすれば、どちらもの機能を果たせる。
しかし、
* たくさん入れると処理が追いつかなくなる
* 障害が発生したときに全ての機能が止まる
これらの問題があるので、複数のソフトを入れるのは、実用的ではない
# サーバーの代表例
| サーバー | 特徴 |
|---|---|
| Webサーバー |Webサイトの機能を提供するサーバー。HTMLファイルや画像ファイル、プログラムを置いておき、クライアントのWebブラウザがアクセルするとファイルを提供する。ex)Apache,Nginx,IIS|
|メールサーバー|メールの送受信をするSMTPサーバーとクライアントにメールを受信させるPOPサーバーを合わせて、メールサーバーと呼ぶ。ダウンロードせず、サーバーに置いたままメールが読めるIMAPサーバーもある。ex)Sendmail,Postfix,Dovecot|
|データベースサーバー|データを保存したり、検索したりするためのデータベースを置くサーバー。ex)MySQL,PostgreSQL,MariaDB,SQL Server,Oracle Database|
|ファイルサーバー|ファイルを保存して共有するためのサーバー。ex)Samba|
|DNSサーバー|IPアドレスとドメインを結びつけるサーバー|
|DHCPサーバー|IPアドレスを自動的に割り当てる機能を持つサーバー|
|FTPサーバー|FTPプロトコルを使って、ファイルの送受信を行うサーバー。Webサーバーとともに格納されることが多い|
|プロキシサーバー|通信を中継する役割を持つサーバーの総称。社内LANなどの隔離された場所からインターネット上のサーバーに接続する時に使う。また、接続先から自分のアクセス元が隠せる。|
|認証サーバー|ユーザーを認証するためのサーバー。ex)Windowsネットワークにログインするための**Active Directory**や無線LANやリモート接続する際にユーザー認証するRadius サーバーなどがある|

# サーバーマシンに必要な要素
サーバーマシンも一般的なコンピューターも構成要素は変わらない。
しかし、用途が違うため、無駄な機能が省かれていて、比較的丈夫に作られている
|用途|内容|
|---|---|
|CPU|パソコンの頭脳|
|メモリ|一時的な記憶装置|
|マザーボード|電子回路基盤。CPUやメモリ、ストレージを接続する|
|ストレージ|補助記憶装置。永続的に残したいデータはストレージに入れる|
|OS|コンピュータを動かすためのシステム。ハードウェアとソフトウェアの仲介をしている|

# サーバー用のOS
代表的なサーバー用のOSには**UNIX系**(LinuxとBSD)と**Windows系**がある。
サーバー用のOSはクライアント用のOSに比べて**多い**
特にUNIX系はオープンソースなので、多様な係累（UNIXから広がったOS）を生み出した。
一方で、Window系はWindows Serverのみ。
# インスタンスとサーバー
Amazon EC2では、サーバーは**インスタンス**として作成される。
インスタンスとは**実態**という意味で、実際に稼働している、仮想化されたコンピュータのことを指す。
ex)
サーバーは**機能のこと**と**物理的なサーバー自身**を指すが、
インスタンスは**サーバーとして稼働している仮想サーバー**のことを指す
**つまり、AWSではサーバーをインスタンスとして作成する**。
Python3: A4横 の PDF を A3 の PDF に変換

例えば 10ページの A4横 の PDF を、５ページの A3 の PDF に変換します。

## プログラム

```py:pdf_a4_a3_landscape.py
#! /usr/bin/python
#
#	pdf_a4_a3_landscape.py
#
#						Feb/01/2023
#
import  sys
import  PyPDF2
from PyPDF2 import Transformation
#
# ------------------------------------------------------------------
def pdf_merge_proc(pdf_reader1):
	deltx = 960
	delty = 1080
	pages= len(pdf_reader1.pages)
	nn_out = int((pages + 1) / 2)
	sys.stderr.write("pages = %d\n" % pages)
	sys.stderr.write("nn_out = %d\n" % nn_out)
#
	pdf_writer = PyPDF2.PdfWriter()
#
	for icount in range(nn_out):
		it = icount * 2
		page_obj_a = pdf_reader1.pages[it]

		page_obj_out = PyPDF2.PageObject.create_blank_page(width=deltx, height=delty)
		op = Transformation().translate(tx=0, ty=540)
		page_obj_out.merge_page(page_obj_a)
		page_obj_out.add_transformation(op)

		jt = it + 1
		if jt < pages:
			page_obj_b = pdf_reader1.pages[jt]
			page_obj_out.merge_page(page_obj_b)
#
		pdf_writer.add_page(page_obj_out)
#
	return pdf_writer
# ------------------------------------------------------------------
sys.stderr.write ("*** 開始 ***\n")
pdf_in = sys.argv[1]
pdf_out = sys.argv[2]
#
pdf_file_in = open(pdf_in, 'rb')
pdf_reader1 = PyPDF2.PdfReader(pdf_file_in)
#
pdf_writer = pdf_merge_proc(pdf_reader1)
#
pdf_output_file = open(pdf_out, 'wb')
pdf_writer.write(pdf_output_file)
pdf_output_file.close()
pdf_file_in.close()
#
sys.stderr.write ("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行方法

```bash
./pdf_a4_a3_landscape.py file_a.pdf file_a3.pdf
```

次のバージョンで確認しました。

```text
$ python --version
Python 3.10.7
```

```text
>>> import  PyPDF2
>>> PyPDF2.__version__
'3.0.1'
```


A4縦の変換はこちら
[Python3: A4 の PDF を A3 の PDF に変換](https://qiita.com/ekzemplaro/items/f719b60dcf44852eaad6)
Oracleでバージョン確認SQL

# やり方

```sql
SELECT * FROM v$version;
```

# 参考サイトさん

https://qiita.com/nkojima/items/35492a7ea632fde0d623

# バージョン

Oracle Database 11g Release 11.2.0.1.0 - 64bit Production

TODO:PL/SQLについて勉強する。
discord.pyで使ったものを置いておこう（随時更新）

# はじめに
discord.pyで使った関数とかをここにそっと置いておきます
自分用でもあり、誰かの役に立てばいいな、と思います

# 重要事項
:::note alert
これから解説するコードたちは
[Discord Developer Portal](https://discord.com/developers/applications/)から
intentsの欄をオンにする必要がある場合があります

その上で、
```python
intents = discord.Intents.all()
client = discord.Client(intents=intents)
```
を記述してください。
これらを行っていないと動かないコードがあるので
```python
AttributeError: 'NoneType' object has no attribute 'status'
```
などのエラーが出た場合は上記を行ってください。
:::
細かい手順等は以下のサイトを参考にしてみてください

https://qiita.com/disneyresidents/items/72741a88265107dd04d3

それでは本題へ。
## メンバーのステータスを確認
```python3
guild = client.get_guild("guild id")  #idはint型で
user_status = guild.get_member("user id").status  #idはint型で

if user_status == discord.Status.online:
```
- 一行目について
  - サーバー（以下ギルド）を取得しています。
  - ギルドを取得するとギルドの情報をたくさん取得できます。

https://discordpy.readthedocs.io/ja/latest/api.html?highlight=message#discord.Guild

- 二行目について
  - メンバーのステータス情報を取得しています。
  - Memberを取得するとMemberの情報をたくさん取得できます。
  
https://discordpy.readthedocs.io/ja/latest/api.html?highlight=member#discord.Member

- 三行目について
  - メンバーがオンライン状態かどうかを判断するif文となってます
  - 比較する際はdiscord.Status.~~という風に書かないとだめみたいです
   （if ~~ == "online"　という書き方ではだめでした。。）

https://discordpy.readthedocs.io/ja/latest/api.html?highlight=member#discord.Status

## メンバーにDMを送信
```python
user = await client.fetch_user("user id")
await user.send("Excuse me, sir?")
```
- 一行目について
  - ユーザーを取得しています。
  - ユーザーを取得するとユーザーの情報をたくさん取得できます。
  
https://discordpy.readthedocs.io/ja/latest/api.html?highlight=user#discord.User

- 二行目について
  - DMを送信しています。
  - Bot起動直後や、指定時間に送信も可能です。

以下例

```python:ex.1 起動直後にDMを送信
@client.event
async def on_ready():
    user = await client.fetch_user("user id")  #idはint型で
    await user.send("Excuse me, sir?")
```
```python:ex.2 14時になったらDMを送信
@tasks.loop(seconds=1)
async def get_time():
    now = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
    if now.hour == 14 and now.minute == 0 and now.second == 0:
        user = await client.fetch_user("user id")
        await user.send("Excuse me, sir?")

@client.event
async def on_ready():
    get_time.start()
```

## embedの中身（文字等）を取得
```python:今回はembedのdescriptionを取得
@client.event
async def on_message(message):
    msg = message.embeds[0].description
```
  - メッセージにembedの情報も含まれている
    - embeds[0]でembedの中身取り出し
    - embed[0].descriptionでembedの説明取得

  - APIリファレンスでembedと検索すると色々でてくるので、タイトルや色も取得可能

## 送られてきた画像URLを取得
```python:今回はembedのdescriptionを取得
@client.event
async def on_message(message):
    url = message.attachments[0].url
```
  - 画像のURLが返ってくる

以下例

```python:ex 送られてきた画像を保存
import requests
from PIL import Image

@client.event
async def on_message(message):
    url = message.attachments[0].url
    filename = "image.png"
    response = requests.get(url)
    image = response.content

    with open(filename, "wb") as f:
        f.write(image)

```
## 今はとりあえずここまで
また調べてわかりにくかったけどいろいろやってたらできた！
みたいなのがあれば載せます～
Goでリリースビルドするときに最低限付けておきたいオプション

みなさん、Goでビルドするときには、どんなオプションを指定していますか？

Goでは`go build`だけでも何事もなくビルドできるので、特に何も指定していないという人もいるかと思います。
しかし、オプションを何も指定せずにビルドした実行ファイルには、デバッグ情報などのリリース時には不要な様々な情報が含まれています。

本稿ではリリースビルドを作成するときに最低限付けておきたいオプションについて、簡単に紹介したいと思います。

※ビルドオプションを網羅的に紹介する記事ではありません。

## リリースビルド時に最低限付けたいオプション

Goでリリースビルドを作成する時に最低限付けておきたいオプションは次の2つです。

- `-ldflags="-s -w"`
  - デバッグ情報（シンボルテーブル等）を含めないオプション
  - ファイルサイズが小さくなります
- `-trimpath`
  - ビルド環境のローカルパス情報を取り除くオプション
  - （ユーザー名などが含まれた）ローカルPC上のパス情報の漏洩を防げます

実際にはこのような感じで使います。

```sh
go build -ldflags="-s -w" -trimpath
```

巷の記事やOSSプロジェクトを見ても、だいたいこのような指定をしているものが多い印象です（`-trimpath`は無いことも多いですが[^1]）。

以下の項でこの2つのオプションについて簡単に解説します。

[^1]: `-trimpath`はGo 1.13（2019年9月リリース）で追加されたオプションです。

### `-ldflags="-s -w"`オプション

`-ldflags`は、ビルド時に内部で呼ばれる`go tool link`の引数を指定するオプションとなっていて、今回の指定では`go tool link -s -w`のような感じで実行されることになります。

`go tool link`に渡せるオプションについては[linkコマンドのドキュメント](https://pkg.go.dev/cmd/link)か`go tool link --help`で確認できます。

`-s`と`-w`についてヘルプを確認すると、次のようなことが書かれています。

```
-s
	Omit the symbol table and debug information.
-w
	Omit the DWARF symbol table.
```

いずれもシンボルテーブルやデバッグに関する情報を取り除くオプションです。
これらのオプションを指定することで、実行ファイルからデバッグ用の情報が取り除かれ、ファイルサイズがそこそこ小さくなります。

ちなみにシンボルテーブルというのは、関数名や変数名、ソースコード上の位置などの情報を格納したテーブルです。
ただ、Goのスタックトレースに出てくる情報はまた別に持っているようで、これらを指定してもスタックトレースではファイル名や位置が出力されます。

#### ファイルサイズについて

簡単なhello-worldプログラムで比較してみると、だいたいこのぐらいの違いが出てきます（Go 1.18 on macOSでの一例です）。

| オプション                   | ファイルサイズ |
| ---------------------------- | -------------- |
| なし                         | 1854560 (1.8M) |
| `-ldflags="-s -w"`           | 1346656 (1.3M) |
| `-ldflags="-s -w" -trimpath` | 1342560 (1.3M) |

### `-trimpath`オプション

`-trimpath`は`go build`に対するオプションです。Go 1.13で追加されました。

`go build`に渡せるオプションについては[buildコマンドのドキュメント](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies)か`go help build`で確認できます。

`-trimpath`についてヘルプを確認すると、次のようなことが書かれています。

```
-trimpath
	remove all file system paths from the resulting executable.
	Instead of absolute file system paths, the recorded file names
	will begin either a module path@version (when using modules),
	or a plain import path (when using the standard library, or GOPATH).
```

通常はビルド環境の絶対パスが実行ファイルに埋め込まれるのですが、これをモジュールや`GOPATH`からの相対パスとして記録するようになります。

#### 埋め込まれるパス情報について

例えば次のようなディレクトリで開発をしているとします。

```
/Users/ynakamura/mycompany/myproject
```

ここで`-trimpath`を**付けずに**ビルドした場合、プログラムがスタックトレースを出力すると、このような感じになります。[^2]

```console
$ ./myproject
panic: error!!

goroutine 1 [running]:
main.main()
	/Users/ynakamura/mycompany/myproject/main.go:4 +0x27
```

ユーザー名や会社名等の含まれた、開発環境のフルパスが見えてしまっていますね。

一方で、`-trimpath`を付けてビルドするとこうなります。

```console
$ ./myproject
panic: error!!

goroutine 1 [running]:
main.main()
	myproject/main.go:4 +0x27
```

プロジェクトディレクトリからの相対パスだけが記録されるようになりました。

[^2]: `strings`コマンドでもファイルに埋め込まれた文字列が確認できます。

## おわりに

これら2つのオプションを指定すると、ファイルサイズは小さくなるし、余計な情報が残らないので、リリース時にはぜひとも付けておきたいですね。

シングルバイナリという特性上、ちょっと大きめなGoのバイナリが小さくなるのは嬉しいかと思います。
特にコンテナ環境が多くなりつつある昨今では、コンテナイメージを少しでも小さくするために色々工夫をすることも多いので、そういった面でも効果が期待できます。

パス情報についても、漏れたからといって直ちに情報漏えい等の問題に繋がるわけではありませんが、ビルド環境のパス情報が見えてしまうのはあまり気持ちの良いものではないですし、サーバーのログに残ったりもするので、できれば消しておきたいですね。
CentOS8にDockerをインストールする

公式の手順どおりやればできました。

https://docs.docker.com/engine/install/centos/

### 1.古いバージョンをアンインストールする
```
$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
```
dockerが入ってなくてもとりあえずやっちゃってOKです。なかったらないよ！と言われるだけ。
### 2.リポジトリを設定する
```
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
```
Dockerに必要なパッケージ(` yum-utils `)をインストールして、リポジトリを登録(` yum-config-manager `)
### 3.Dockerエンジンのインストール
やり方は主に二つ。
* 最新バージョンの Docker Engine、コンテナー、および Docker Compose をインストールする
* 特定のバージョンをインストール

バージョンにこだわりはないので、今回は前者のパターンで入れます！
```
$ sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
```
途中で何回か` Is this ok [y/N]: `と聞かれたので全部`y`にしました。
### 4.Dockerを起動する
```
$ sudo systemctl start docker
```
特にメッセージは出てきません。
### 5.Dockerエンジンが正しくインストールされていることを確認
```
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:53f1bbee2f52c39e41682ee1d388285290c5c8a76cc92b42687eecf38e0af3f0
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

```
samでCloudWatchLogsのログ記録を有効化しようとすると「CloudWatch Logs role ARN must be set in account settings to enable logging」と出る

## エラーメッセージ

```
CloudWatch Logs role ARN must be set in account settings to enable logging
```

## 原因
API Gatewayに設定するCloudwatchLogs書き込み用のRoleがセットされていないから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/49ccb0cf-4927-b57d-4e02-99c62fbe7135.png)

## 対処方法
このように、Roleをセットする。

```yaml
Resources:
  ApiCWLRoleArn:
    Type: AWS::ApiGateway::Account
    Properties:
      CloudWatchRoleArn: !GetAtt CloudWatchRole.Arn

  CloudWatchRole:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            Action: 'sts:AssumeRole'
            Effect: Allow
            Principal:
              Service: apigateway.amazonaws.com
        Path: /
        ManagedPolicyArns:
          - 'arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs'

```


## 参考
https://serverless-observability.workshop.aws/en/050_logging/logging-producers/api_logs.html
SaaS、PaaS、IaaS

# SaaSとPaaS、IaaSの違い
これらの違いは**どこまで提供するクラウドサービスなのか**です。
## SaaS（Software as a Service）
インフラやプラットファーム（OS）だけでなく、アプリケーションまでを提供する。
ex)SNSやブログサービス、Webメールサービス、DropBox
## PaaS（Platform as a Service）
プラットファームまでを提供する。OSの入った状態のサーバーにアプリケーションなどをインストールして利用する
ex)レンタルサーバー
## IaaS（Infrastructure as a Service）
インフラのみ、すなわちネットワークやサーバーなどのマシンを提供
# EaaS（Everything as a Service）・XaaS（ザース）
SaaS、PaaS、IaaSの総称をEaaSやXaaSと呼ぶ
ネットワークからソフトウェアまでを提供するサービスのこと。
つまり**AWSはEaaS**。
# 3つのサービス形態の特徴
SaaSは便利な反面、自由度が低い
IaaSは設定が複雑な反面、自由度が高い
## SaaS
* 便利である反面、自由度が低い
* すぐに使うことができるため、手間が少ない
* 特別な知識は不要
* 端末以外に自前で用意するものはない
## PaaS
* 好きなアプリケーションを入れられるが、対応していないアプリケーションもある
* サーバーを管理する知識が必要
* 場合によってはアプリけーshジョンを用意する必要がある
## IaaS
* 使うにはセッティングが必要
* サーバーを管理する知識が必要
* 場合によってはアプリケーションを用意する必要がある
# その他のクラウドサービス形態
## DaaS（Desktop as a Service）
普段使っているパソコンの中身を仮想化してネットワーク上におくサービス。
ユーザーはネットワーク越しにリモートで操作できる。たとえば、会社のパソコンをDaaS化して会社でも家でも同じ環境で作業できる
## FaaS（Function as a Service）
関数を置くと実行させるサービス。サーバーレスと呼ばれるシステムで、
AWSでは**Lambda**がFaaSに該当する。
Docker Desktop for macでgRPCが設定できない!?

# 結論｜セッティングファイルで設定できた
docker Desktop for macにはCLIはないようですがセッティングファイルがありました。
ファイルの場所はM1Macの場合以下にありました。
~/Library/Group Containers/group.com.docker/settings.json

ただ肝心のgRPCに関する項目っぽいものが見当たらず
検索してみたところ以下の方法を見つけました。
以下の手順でfeatures-overrides.jsonというファイルを作成して設定を追加しています。

```shellscript
% cd ~/Library/Group\ Containers/group.com.docker
% code features-overrides.json
```

そして以下を追加し、Docker Desktop for Macを再起動したところgRPCのチェックを外した状態で起動することができました。

```features-overrides.json
{ "grpcfuseV2": { "name": "", "label": "Use grpcfuse for filesharing by default", "enabled": false } }
```

# 状況
今回Docker Desktop for Macのおそらくバグでアップデートをきっかけに
リセットも再インストールもできない状態になり、スタートしても
Docker Desktop is startingが延々続くという状態になってしまいました。
そして解決策を探っている中で今回の設定方法を見つけられました。

# CLIツールが欲しいですね
今回のような状況でDocker Desktop for MacのCLIツールを探している方もいるかと思いますが私が探してみたところ現状ではなさそうです。

https://github.com/docker/roadmap/issues/172

CLIツールも欲しいですがコミットできる力が欲しいです。

# 参考
今回ArxXxさんのコメントがなかったらこのやり方を見つけられなかったかもしれません。感謝です。

https://github.com/docker/for-mac/issues/5113#issuecomment-1089891951
Ubuntuでロックファイルを握りっぱなしになった時の対処法

Ubuntuはパッチ適用に問題を抱えていると個人的には考えている。
bootして数分以内にアップデート確認ダイアログが出るわけだが、あれがどうも
ロックファイルを握りっぱなしになるケースが頻発しているように見える。

これの対処は[[Ubuntu][apt] /var/lib/apt/lists/lockが不正な状態になった場合の対応メモ](https://qiita.com/koara-local/items/e63b7e4ff3cea803bdea)

これに類する対処が検索でよくヒットする。だが、この対処法は日本じゃあ二番目だ。

ロックファイルを削除して、強制的にアップデート可能にしてしまえ！
ではなく
ロックファイルを握っている人のお行儀が悪いなら死んでもらえ！
が理にかなった対処方法ではなかろうか？

```
ps aux | grep -i apt
sudo kill -9 PID
```

参考：[Ubuntuで 'E：ロックを取得できませんでした/ var / lib / dpkg / lock'エラーが発生しました[クイックヒント]](https://websetnet.net/ja/fix-e-could-not-get-lock-var-lib-dpkg-lock-error-in-ubuntu-quick-tip/)

これで動作中のaptプロセスのPIDを探し出し、sudo kill -9 PIDで死んでもらう。
ロックファイルは解放され、sudo apt update / upgradeが可能になる。

あまりにも頻発するので、これaptのバグじゃないかと疑っている。
pre-commitにpyrightを追加する


# はじめに

[pre-commit](https://pre-commit.com/) という、gitのpre-commitフックへのスクリプト追加を容易にするツールがある。
最近のPythonツール界隈はだいたいこのpre-commitに対応しているのだが、 [Pyright](https://github.com/microsoft/pyright) は対応していない。

https://github.com/microsoft/pyright/issues/3612

素直に公式対応してほしいのだけど、erictrautさんが紹介している方法でも実現はできるのでまあそれを使う。

# やり方

パッケージマネージャーにpoetryを使っている前提です。

1. `poetry add -D pyright==1.1.265` する
1. `.pre-commit-config.yaml` に以下を追加する

    ```yaml
    
    repos:
    #...
      - repo: local
        hooks:
          - id: pyright
            name: pyright
            entry: pyright
            language: node
            pass_filenames: true
            types: [python]
            # Replace the version below with the latest pyright version
            additional_dependencies: ['pyright@1.1.265']
    #...
    ```

`pass_filenames` はfalseにしているとステージングされたファイルだけでなく、リポジトリー内の全てのファイルを対象にしてしまうので必ずtrueにする。
複数AWSアカウントでCodeCommitにアクセスする認証情報を切り替える方法（Windows環境）

# 目的
備忘録。

複数のAWSアカウントでCodeCommitを利用する際に資格情報を切り替えるのが面倒に感じたため、その手順を残します。
ちなみに同一AWSアカウントでの複数IAMユーザ切替えでも同様です。

# 環境
- Windows 10
- git version 2.31.1.windows.1

# やり方
Gitでcloneする際にnamespaceを指定することで、Windowsの資格情報マネージャで個別に資格情報を管理することができます。
ただし、そのままだと`.git/config`に反映されないので手動で反映する必要があります。
```
【Git clone】
git -c credential.namespace=${NAMESPACE} clone ${REPOSITORY_URL} ${DEST}

【設定を追加】
cd ${DEST}
git config credential.namespace ${NAMESPACE}
```

## スクリプト
定型処理なのでスクリプトファイルにしてパスを通したフォルダに置いて使います。※PowerShellはBOM付きで保存してください。
また、よく使うnamespaceはデフォルトに設定しておくと使いやすくなります。
```powershell:gitc.ps1
param (
    [parameter(mandatory = $true)][String] $namespace = "",
    [parameter(ValueFromRemainingArguments = $true)] $others
)

if (${namespace}.IndexOf("https://") -eq 0) {
    ${tmp} = @(${namespace}, ${others})
    ${others} = ${tmp}
    ${namespace} = "デフォルトにしたいnamespace"
}

if ($others[0].IndexOf("https://") -ne 0) {
    Write-Host "[Error] git clone の引数を指定してください"
    exit 1
}

if ("${namespace}" -eq "" ) {
    Write-Host git clone ${others}
    git clone ${others}
    exit
}

Write-Host git -c credential.namespace=${namespace} clone ${others}
git -c credential.namespace=${namespace} clone ${others}

$dest = Split-Path $others[0] -Leaf

if (-Not $(Test-Path $dest)) {
    Write-Host "[Error] クローンしたディレクトリが見つかりません: ${dest}"
    exit 1
}

Push-Location ${dest}
git config credential.namespace ${namespace}
Pop-Location
```

# 所感
どのAWSアカウントの資格情報でアクセスするのかスッキリ。
ちなみに資格情報の確認と削除は「資格情報マネージャー」から行えます。
【Excelアドイン】Excelのフォーミュラを出力する

[Sharperlight](https://sharperlight.jp/)クエリビルダでExcel上にレポートを設計する場合、時にExcelのフォーミュラもクエリ結果として出力したい場面に遭遇します。そのTipを記事にします。

ここにこのようなクエリがあり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/71da1b1a-8990-158c-2af0-8109c673dd19.png)
クエリ結果はこのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/4f0196ee-5801-8f1a-bbf3-363f1c7ac024.png)
では、拡張表現を追加します。
今回はIFERROR式とROUND式のコンビネーションを出力してみます。
ROUND式でエラーが発生した場合に、空白を返すようにします。
拡張表現のテキスト欄にこのように記述します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/8fae5213-baf2-610d-5cc6-c6b793e54d4a.png)
ポイントは2か所、ひとつ目は、式の前後をシングルコーテーションで囲むこと、ふたつ目は、データ型に`HTML`を指定することです。
セル参照は、ターゲットのセルをきちんと参照するように指定してください。
このクエリ式は、セルC3に定義されるので、数値AはセルC5、数値BはセルD5が開始セルとなります。
結果はこのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/66ddf758-e967-7e52-4ada-a63d7d1961bc.png)
エラーが返されるであろうセルにきちんと空白が表示されていますね。
Excelフォーミュラもきちんと設定されていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/ba249de6-95c9-35ae-c53b-ba02d0d7418d.png)
Linuxカーネルのモジュール管理

対象者：LPICレベル２学習者
カーネルを構成するモジュールの説明とモジュールの操作や情報表示のためのコマンドについてまとめました。
# 目次
・カーネルモジュールの定義
・カーネルモジュールの仕組み
・カーネルモジュールの配置ディレクトリ
・モジュール操作コマンド
## カーネルモジュールの定義
カーネルモジュールは、カーネルを構成する機能を分離してモジュール化したものです。　
例：デバイスドライバ
## カーネルモジュールの仕組み
Linuxカーネルには、ローダブルモジュールのサポートを有効にした場合、カーネルの機能の一部をモジュール化し、カーネルから分離して、必要な時に読み込んで使用することができます。この仕組みによって、以下のメリットがあります。
**・カーネル本体のサイズを小さくし、起動に要する時間の短縮と多種多様なハードウェアに対応できる。**
**・不要な機能を外すことでカーネルが使用するメモリの節約ができ、USB機器などのホットプラグ対応デバイスの取り付け、取り外しが可能。**
## カーネルモジュールの配置ディレクトリ
配置ディレクトリは「/lib/modules/カーネルのバージョン」で、このディレクトリ以下に、機能ごとのサブディレクトリに分けて配置されています。
知っていて当たり前-14　ベクトルのプッシュとポップ

# 知っていて当たり前-14　ベクトルのプッシュとポップ

プッシュとポップ　push, pop

他の関数と同じく以下でも関数名の最後が `!` の場合は，インプレースで実行される。

## 1.　先頭にプッシュする `pushfirst!()`

戻り値はプッシュされた後の引数と同じ。


```julia
a = [1, 2, 3]
x = pushfirst!(a, 0)
(x, a)
```




    ([0, 1, 2, 3], [0, 1, 2, 3])



## 2.　先頭をポップする `popfirst!()`

戻り値はポップされた値。変数に代入しなければ捨てられるだけ。


```julia
b = [11, 12, 13, 14]
x = popfirst!(b)
x, b
```




    (11, [12, 13, 14])



## 3.　末尾にプッシュする `push!()

戻り値はプッシュされた後の引数と同じ。


```julia
c = [1, 2, 3, 4]
x = push!(c, 99)
(x, c)
```




    ([1, 2, 3, 4, 99], [1, 2, 3, 4, 99])



## 4.　末尾をポップする `pop!()`

戻り値はポップされた値。変数に代入しなければ捨てられるだけ。


```julia
d = [21, 22, 23]
x = pop!(d)
(x, d)
```




    (23, [21, 22])



## 5.　任意の位置にプッシュする `insert!()`

戻り値は挿入された後の引数と同じ。


```julia
e = [31, 32, 33]
x = insert!(e, 2, 999)
(x, e)
```




    ([31, 999, 32, 33], [31, 999, 32, 33])



## 6.　任意の位置からポップする `popat!()`

戻り値はポップされた値。変数に代入しなければ捨てられるだけ。


```julia
f = [31, 32, 33]
x = popat!(f, 2)
(x, f)
```




    (32, [31, 33])



## 7.　任意の位置の要素を削除する `deleteat!()`

戻り値は削除された後の引数と同じ。


```julia
g = [41, 42, 43, 44]
x = deleteat!(g, 3)
(x, g)
```




    ([41, 42, 44], [41, 42, 44])



## 8.　ベクトルの長さ（要素数） `length()`


```julia
h = [1, 2, 3]
length(h)
```




    3



## 9.　空ベクトルか? `isempty()`


```julia
isempty(h) 
```




    false



## 10.　空ベクトルにする `empty!()`

戻り値は空ベクトル。


```julia
x = empty!(h)
(x, h)
```




    (Int64[], Int64[])
Railsのdeviseで新規登録の際に親テーブルの外部キーをパラメーターに渡す

## 実装背景
deviseを使ったユーザー管理を実装していますが、パラメーターに親テーブルのidを渡してユーザー新規登録を実装する必要がありました。
具体的には下記のようなURLで新規登録画面を開くことを目標とします。
```
/admin_groups/:admin_group_id/admin_users/sign_up
```



## 該当DB
管理会社テーブル
| admin_groups |
| ---- |
|name|

管理者テーブル
| admin_users |
| ---- |
| name |
| email |
| password |
| admin_group_id |

## 新規登録フロー
参考までに今回実装予定の新規登録フローを紹介します。
1. 既に登録されているユーザーがログインする。
1. 新規ユーザー招待画面で招待したいユーザーのメールアドレスを入力、送信
1. 届くメール本文には、自動で新規登録画面のURLが記載されている。
1. URLのパラメータにはログインユーザーのデータに入っているadmin_group_idが自動で入り、同じ管理会社の所属になる。

## ルーティングを設定
```routes.rb
  devise_for :admin_users, skip: :all #'registrations'
  devise_scope :admin_user do
    get '/admin_groups/:admin_group_id/admin_users/sign_up', to: 'admin_users/registrations#new', as: 'admin_user_registration'
  end
```
1行目でadmin_usersをマッピングしています。2行目以下でregistrationsコントローラーの記述がありますので、registrationsはskipさせます。
この1行がないと、devise_mapping.validatable?の箇所でNoMethodError in Admin_Users::RegistrationsController#newエラーが出ます


2〜４行目で/admin_groups/:admin_group_id/admin_user/sign_upへアクセスされたときのコントローラーとアクションを指定します。
devise_scopeの後のadmin_userは単数系です。
複数形にすると、同様にエラーになります。

## あとがき
新規登録に関してはこれでルーティングができました。
ログインに関しては親テーブル関係なく、admin_users/sign_inで行いたいので下記に手順を書きました。
[Railsのdeviseで新規登録画面URLは親テーブルのidを渡し、ログインURLには渡さない](https://qiita.com/r-kubo/items/2bc8707daabbb7e99c10)
Address already in use - と言われました

rails s

を実行したところ。
エラーに

＃省略
Address already in use - bind(2) for "127.0.0.1" port 3000 (Errno::EADDRINUSE)
＃省略

と表示された。


エラー文の意味
既に3000番ポートが使われているということ。
3000ポートは既に使われるからサーバーと繋げられない。

参考：
https://qiita.com/A__Matsuda/items/78b5c3f8c6578d807e09



やること:
使用しているプロセスを切る必要がある。切った後に

コマンド
rails server

ブラウザ
http://localhost:3000

でrailsが正常に動作するか確認する。


1.既に繋がっているポート番号の特定：
$ lsof -i:指定番号(,2個目以降ある時の指定番号)

2.実行後に表示されたポートのPID項目を調べる。

3.kill -9 [PIDの数字]　
(-9をつけると強制終了)で強制終了に持ち込む。
4.

コマンド
rails server
ブラウザ
http://localhost:3000
で動作確認。

実行したところ、解決できました。


参考にしたもの：https://qiita.com/A__Matsuda/items/78b5c3f8c6578d807e09
https://qiita.com/growsic/items/5c1626f60b5e5538d2b3
https://qiita.com/hypermkt/items/905139168b0bc5c28ef2
https://qiita.com/motty93/items/d22c1eb8f5128f8cd7f8
Linux 制御演算子・シェル変数・環境変数について（自分用メモ

制御演算子「&&」は、command1が成功した場合のみcommand2を実行。
「&&」はAND（論理積）を意味する演算子です。以下のように実行すると、command1の実行が失敗するとAND条件が成立しないため、command2は実行されません。command1の実行に成功した場合のみcommand2が実行。

制御演算子「||」は、command1が失敗した場合のみcommand2を実行。
「||」はOR（論理和）を意味する演算子です。command1の実行が成功すればその時点でOR条件が成立するためcommand2は実行されません。command1の実行が失敗した場合はOR条件に従ってcommand2が実行。




●コマンドや設定ファイルのためのオンラインマニュアルページ(manページ)を参照するコマンドはman。

man [オプション] [セクション番号] キーワード

オプション
・-k キーワードに一部一致するコマンドやファイルのmanページを一覧表示（aproposコマンドと同じ）
・-f キーワードに完全一致するコマンドやファイルのmanページを一覧表示（whatisコマンドと同じ）


同じキーワードにmanページが複数用意されている場合(例えばpasswdコマンドと「/etc/passwd」ファイル)は、セクション番号を指定してmanコマンドを実行することで、目的のmanページが参照できます。

●manページのセクション番号は以下の通りです。
・1 ユーザコマンド
・2 システムコール（カーネルが提供する関数）
・3 ライブラリ呼び出し（プログラムファイルに含まれる関数）
・4 特殊ファイル（通常/dev 配下に存在するファイル
・5 ファイルの書式と慣習（例　/etc/passwd）
・6 ゲーム
・7 その他いろいろ（マクロパッケージや慣習を含む）
・8 システム管理コマンド（通常はroot用）
・9 カーネルルーチン［非標準］


例）passwdコマンドのmanページを参照する場合
$ man 1 passwd

例）「/etc/passwd」ファイルのmanページを参照する場合
$ man 5 passwd

なお、セクション番号を指定しないで実行した場合は、セクション番号の小さいほうのマニュアルが表示される


●主なメタキャラクタ（シェルによって特別に解釈される文字）、ディレクトリ関連の特殊記号をまとめたもの。

・*　０文字以上の文字列
・? 任意の１文字
・[] []内のいずれか１文字
・$ 変数
・’ 「’」で囲まれた部分を文字列とみなす
・” 「”」で囲まれた部分を文字列とみなす。ただし「$」「’」「¥」「”」は除く
・` 「`」で囲まれた文字列（変数の場合は格納されている値）をコマンドと見做し、その実行結果を文字列として返す
・¥ 次の文字（メタキャラクタ）の意味を打ち消して通常の文字として扱う「\」も


●あらかじめ用意されている代表的な環境変数。
・HISTFILE コマンド履歴保存ファイルのパス
・HISTSIZE 現在のシェルでのコマンド履歴の保存数
・HISTFILESIZE コマンド履歴保存ファイルへの履歴保存数
・HOSTNAME ホスト名
・HOME ログインしているユーザのホームディレクトリ
・LANG ロケール（言語設定）
・PATHコマンドやプログラムを検索するディレクトリのリスト
・PWD カレントディレクトリのパス
・USER ログインしているユーザ


●Linuxで使用できる変数には、シェル変数と環境変数があります。

●シェル変数
変数を設定したシェル上でのみ有効な変数。シェル変数は以下のようにして作成することができます。

シェル変数名=値

シェルはパスの指定無しで入力されたコマンド（プログラム）を、環境変数PATHに設定されているディレクトリの中から検索して実行します。これらのディレクトリは「パスが通っている」という言い方をします。
パスが通っているディレクトリにあるコマンドであれば、コマンドの格納されているパスをいちいち指定せずに、コマンド名のみでコマンドを実行することが出来ます。

環境変数PATHには通常、以下のように複数の値（ディレクトリ）が「：」で区切られて設定されています。
$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

パスを指定せずにコマンドを入力すると、上記のディレクトリを左から順に、入力されたコマンドと同名のプログラムファイルが探され、存在すればそれが実行されます。

環境変数PATHに値を追加する場合は「export PATH=$PATH:値」のようにして行います。
「$PATH」の部分が、現在設定されている値に変換されますので、そこに値を追加するという事です。

例）環境変数PATHに「/usr/local/test」ディレクトリを追加する場合

$ export PATH=$PATH:/usr/local/test
$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/test



●環境変数
変数を設定したシェル上と、そこから起動されるシェルやアプリケーション、コマンドで有効な変数。これは設定が引き継がれる事を意味します。
環境変数はexportコマンドを使用して作成することができます。

export 環境変数=値　

また、exportコマンドはシェル変数（変数を設定したシェル上でのみ有効な変数）を環境変数に変更できます。

export シェル変数名


設定されている変数を一覧で確認するには以下のコマンドを使用。
コマンド
・set 全てのシェル変数と環境変数を表示
・env 全ての環境変数を表示
・printenv 一部、または全ての環境変数を表示

echoコマンドを使用して、個々のシェル変数または環境変数の値を確認することもできます。値を確認したい変数の先頭に「$」をつけたものを引数に指定します。設定されている変数を一覧で確認するには以下のコマンドを使用します。


●すでに設定されている環境変数やシェル変数を削除するコマンドはunset。

unset 変数名


●シェルには様々なオプション機能があります。シェルのオプション機能はsetコマンドで有効・無効を設定します。

set [-o][+o] オプション

オプション
・allexport 新規作成・変更した変数を自動的に環境変数とする（エクスポートする
・emacs emacsエディタと同じキーバインドにする
・ignoreeof Ctrl+Dをおしてもログアウトしない設定にする
・noclobber リダイレクト演算子「>」「>&」「<>」で既存のファイルを上書き不可に設定する
・noglob パス名展開を無効に設定する（ワイルドカードによる展開(*や?)が無効になる）
・vi viエディタと同じキーバインドになる

オプションを有効にするには「-o」を指定し、解除するには「+o」を指定します

set」コマンドを引数なしで実行すると、設定済みのシェル変数や環境変数、シェル関数が表示
IT初心者がExcelショートカットキーを教わってみた

**【IT】【エンジニア】** 
という言葉だけを知っている人間が実際に足を踏み入れてみました。
本当に<font color=" #228b22 ">**初心者**</font>である今でしか残せないであろう、IT業界に入った理由や現状を投稿します。

# なぜIT業界に入ったのか
**【IT】【エンジニア】**
という名前だけを見ると
頭よさそうだなぁ
かっこいいなぁ
すごい人なんだろうな～
難しそうだなぁ
そんな風にぼんやりと思っているだけでした。

私はどちらかというとアナログ人間で
メモを取るときはポケットからメモを取り出し
入部募集ポスターを作るときはシャーペンと消しゴムを握る。
ゲームをするときの＜オンライン＞は
どうぶつの森のゲームをするときにネットで配布しているお洋服が欲しくて調べたし
インターネットに接続する＜Wi-Fi＞という存在をiPhone8からiPhone11に機種を変
更したときに知りました。

義務教育の中でパソコンを使わなかったと言ったら嘘になるけれど
何をしていたの？と聞かれると言葉に詰まってしまいました。
全員が全員そうかと言われたらそうでもないですが
私の周りには同じような認識、知識の友達が沢山いました。

そんな私には**IT**も**エンジニア**も凄いものに思えました。
ITの〇〇さん
エンジニアの〇〇さん
パソコンに詳しい〇〇さん
、、、なんかカッコいい！

本当にそんな興味だけで入りました。
下心を付け加えると周りの人に頼ってもらえるかも！
すごいって言ってくれるかも！
手に職つけられるかも！
そのぐらいの気持ちが**入り口**でした。

# これから
そんな<font color="red">IT業界未経験</font>の私が弊社に入って
- 何を覚えていくのか
- 何を学んでいくのか
- 何ができるのか
- 
**技術面**でも**考え方**としても優秀とは言えない頭で、
覚えたことをドンドン吸収していき<font color="red">アウトプット</font>する場として
この場所をお借りしていければと思います。

そんな知識0の私が最初に学んだのは<font color=" #228b22 "> **Excel** </font>についてでした。

# <font color=" #228b22 "> Excel初心者</font>が最初に教わったこと（ショートカットとは？みたいな人向け）


まずは<font color=" red ">初心者</font>が<font color=" #228b22 "> WindowsPC </font>で
**これさえ覚えてれば何とかなるよ！**
と言われた<font color="red">ショートカットキー</font>をまとめました！
とても身近な**Excel**ですがこの業界でも必要不可欠なツールとのこと。
私自身のため教えてもらったことを<font color=" red ">**アウトプット**</font>していこうと思います。

例えばこんな時に覗けるメモを<font color=" red ">実用的</font>に使うにあたり
私自身のリアル目線コメントもつけて自由に語ります。

:::note info
- 知っているはずなのにうっかり忘れた時
- 念のため確認する時
- 意識して使うため開いておきたい時
:::

余談ですが私は分からない事があるとすぐもやもやしてしまう性格をしており、
分からない事があった瞬間即知りたい性分なのですが小心者なので聞き返すのが苦手です。
なので常に周りはメモだらけです。
メモを見たり書いたりすることは良いことです。
# 1  ctrl+c  コピー
めちゃくちゃよく使います。
最初の1.2日意識して使ったら体が覚えます。
いずれ位置も覚える。
# 2  ctrl+v  ペースト
めちゃくちゃよく使います。パート2
コピーの隣！！と念じながら指を動かすとコピーのついでに体に染み込む
# 3  ctrl+x  切り取り
めちゃくちゃよく使います。パート3
コピーの（あまり使わない方の）隣と念じながら指を動かすとコピー＆ペーストのついでに体に染み込みます。
# 4  ctrl+s  上書き保存
覚えておくと自分が助かります。
パソコンが急に落ちたりデータが消えることもあるそうなので、意識して保存をしましょう。
覚えたら未来の自分を救うかもしれない。
（一度消えてみると身に沁みます。泣）
# 5  ctrl+z  1つ戻る
ここまでショートカットキーを覚えた時、もうマウスを握るのが億劫になってきませんか？
今までの調子でctrlに指を添えたまま上記vcxの奥の残りのキーって覚えていました。
間違えれば間違えるほど体に染みつきます
ちなみに１つ進むは**crtl+y**
指が攣りそうになります。多分慣れです。
# 6　Windows+l　画面ロック
最初聞いた時必要なのか？と正直思いました。
ただこれこそがIT業界ならではなのかもしれないです。
席に人がいないのに作業画面がついたままでは情報漏洩に繋がります。周りからもセキュリティ面の信頼を失います。
席を立った時画面が暗くないとおかしいなと思えるぐらいに<font color="red">**セキュリティ保持**</font>として癖にしましょう。
# まとめ
とにかく最初のうちは**ctrl**に指を添える事を習慣にする事が大切なのかなと思いました。
よく使う物はそれだけ覚える機会が多いという事なので頭に
・マウスは面倒くさい
・ショートカットは楽
と早く覚えさせます。
（実際に早い）

私も早く<font color="red">**ショートカットキーマスター**</font>になりたいです。
Linuxカーネルのバージョン

対象：LPIC201学習者
Linuxカーネルのバージョンの番号の意味と関連するコマンドについてまとめました。
# 目次
・カーネルとは
・カーネルのバージョン番号の意味
・バージョンを確認するコマンド
#  カーネルとは
カーネルはOSの中核となるプログラムです。ハードウェアの管理やプロセススケジュールリングなど、OSの基本機能を提供します。
# カーネルのバージョン番号の意味
カーネルのバージョン番号は「2.6.X.Y」のように４桁で表します。「Y」の部分は「2.6.X」の修正リリースを表します。　例：2.6.28.1
また、「X」の後に追加される記号からリリースの種類を判別できます。
注）カーネル2.6.39の次のバージョンは3.0としてリリースされ、これ以降は３桁のバージョン番号になります。
１桁目がメジャーバージョン
２桁目がマイナーバージョン
３桁目が安定版
### 種類
-rcN　リリース候補
-gitN　開発盤的な要素をもっているもの
# バージョンを確認するコマンド
バージョンを確認する方法は３つあります。
１．unameコマンド
２．/proc/version
３．カーネルのMakefileを参照
## unameコマンド
現在稼働しているカーネルのバージョンを確認します。
### unameコマンドの主なオプション
-a すべての情報を表示
-r　カーネルのバージョンを表示
-m　ハードウェアアーキテクチャを表示する
## /proc/version
テキストエディタで開いてバージョンを確認することができます。
例：　vim /proc/version
## ソースコードのMakefileから確認
Makefileはカーネルソースがインストールされているトップディレクトリにあります。
### トップディレクトリ
/usr/src/linux
/usr/src/kernels/カーネルバージョン
/usr/src/linux-headers-カーネルバージョン
社内チャットをTeamsとDynamics 365 カスタマーサービスで実施

## 社内チャットをTeamsとDynamics 365 カスタマーサービスで実施する

## ユースケース
これまで電話やメールで社内の問合せを管理していた。
今後はチャットで行い電話、メールの対応を減らす。

### 対応内容
Teamsにチャットボットを組み込み簡単なチャット内容は自動BOTで行う。どうしても解決できない内容はチャットで行う。
リアルタイムで問合せをしない場合は、メールまたはフォームから問合せを行い、オペレータはDynamics 365 の問合せケース画面から回答する。（メール回答は不要となりDynamics 365 画面上で回答する）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/67ad91d9-cbcc-d2fa-364d-c78db0483039.png)

### Teamsにチャットアプリを用意し、チャットを行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/47bc6ee3-b9a9-e141-137d-2c4ce38170d5.png)

### Dynamics 365 Customer Service側でチャットがリアルタイムでくるため
承認を押しチャットを開始する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/3a5a64df-eaf1-d7eb-03a9-94949338760f.png)

### チャットした人の情報とチャット内容がDynamics 365 に格納する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367026/a03471ae-5f8f-3834-6bb0-16d38e8ce3e5.png)

参考

https://docs.microsoft.com/ja-jp/dynamics365/customer-service/configure-microsoft-teams?tabs=customerserviceadmincenter
【Rails6】入力テキストの改行とURLのリンクの有効化

## はじめに
ポートフォリオを作成する中で、入力フォームで登録した内容をビューで表示させると、改行できていない・URLが有効化されていないということに気付きました。
URLについては、入力フォームでurl_fieldを使用すれば簡単に解決できるかと思います。しかし、今回は、入力フォームに普通の文章とURLを混ぜ合わせて入力できるようにしたかったので、違う方法での実装を考える必要がありました。
そんなに難しい内容ではありませんが、記事にまとめることにしました。
## 実装環境
Ruby 3.1.2
Rails 6.1.6

## 実装方法
### 前提条件
モデル　：Book（インスタンス変数として`@book`を使用します）
┗カラム：content
今回は、Bookモデルのcontentというカラムを表示させることにします。

### 【入力テキストの改行の有効化】
一般的にには、以下のように記述すると思います。
```html
<%= @book.content %>
```
しかし、これだとtext_area等の入力フォームで改行しても、表示される時には改行が反映されていません。
そこで、以下のように記述することで、改行を反映させることができます。
```html
<%= safe_join(@book.content.split("\n"),tag(:br)) %> 
```
適宜、`@book.content`の中身を変えてください。
余談になりますが、`simple_format`というヘルパーを使用しても改行を反映させることができます。
しかし、その場合には、空白の改行は無効化されてしまうので、ご留意ください。


### 【URLのリンクの有効化】
こちらには、gemの[rinku](https://github.com/vmg/rinku)を使用します。
まずは、Gemfileに書き込み、`bundle install`します。
あとは、該当のviewファイルに以下のように記述するだけです。
```html
<%= Rinku.auto_link(@book.content, :all, 'target="_blank"').html_safe %>
```

### 【統合】
以下の記述で、上記の2つを組み合わせることができます。
`rinku`の記述の中に、`safe_join`を入れ込むだけです。
```html
<%= Rinku.auto_link(safe_join(@book.content.split("\n"),tag(:br)), :all, 'target="_blank"').html_safe %>
```

## さいごに
以上で改行とURLの有効化が実装できました。
簡単かつUI/UXの向上にもつながるのでおすすめです。
この記事が、どなたかのお役に立てれば幸いです。
ABAPmeterのススメ

従来のアップグレードやシステム移行では、OS/DB構成はそのままで、最新HWへ更新を伴うため、パフォーマンス問題はあまり発生しませんでした。
cloudへのリフトや、S/4HANA化を行うと、Cloudならではの特性、インスタンス構成変更、DB変更の影響を受けて、パフォーマンス問題が発生する事が多いです。

そんな時、個別にトレースをとっても良いのですが、BASISだけでできる調査がABAPmeterです。
これは、ABAP実行環境の調査なのでアプリ視点で調査ができます。

実施方法は、下記の通り。

    Transaction ST13 -> perf_tool -> ABAPMETER
    OR
    Transaction SE38 or SA38 -> Program /SSA/CAT -> Execute (F8)　　

実行時間は１～２秒なので悩むくらいならすぐやりましょう。
結果はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2587098/e4667a93-d9d9-dd6c-48bc-84b98a433386.png)


このようにベンチマーク結果のみが表示されます。
これだけではどこに原因があるか特定は困難ですが、現/新の比較であればどこが問題なのかすぐに特定できます。
尚、クラウド環境でのパフォーマンス問題はだいたいはAP-DB間のネットワークレイテンシの問題のことが多いです。


ちなみに、クラウド上で本稼働させた後も、定期的にモニタリングしたほうが良いと、Note.1612283に書いてありました。
なるほど、クラウド環境では、VM下のレイヤの状況がわかりませんが、特定の指標でパフォーマンスチェックしておくことで、クラウドの基盤不調を察知できるかもしれないですね。

2879613 - ABAPMETER in NetWeaver AS ABAP
1612283 - Hardware Configuration Standards and Guidance
UnrealEngineでPointerIndexが同じWidgetInteractionが複数ある場合におきること

UnrealEngineで作成した自プロジェクトでPointerIndexが同じWidgetInteractionを複数存在させてしまうバグを調査した時に調べた内容をまとめておきます。

# 確認環境

UE4.27.2

# 確認内容

## PointerIndexが異なる際の挙動

![ezgif-5-c2d7ba3ea2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/815a1846-0978-aed3-422c-545187ad68b1.gif)

* 2つのWidgetInteractionに対してWidgetはそれぞれ反応する。
* WidgetのOnPressもOnClickも発火する。

## PointerIndexが同じ場合の挙動

![ezgif-5-750d0f45d8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/70f3401f-1d07-d6c4-fde1-38cbdc79805f.gif)

* ホバーはどちらか片方のWidgetInteractionのみ反応する。
ホバーが反応する方のWidgetInteractionをA、もう一方をBとする。
* AがWidgetを指していて、AでクリックするとOnClickもOnPressも反応する。
* AがWidgetを指していて、BでクリックするとAのクリックとしてOnPressのみ反応する。
* AがWidgetを指していなくて、BでクリックするとBのクリックとしてOnPressのみ反応する。

## 確認用のBlueprint

### WidgetInteractionを持つキューブのBP

![スクリーンショット 2022-08-08 105545.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/23e6cb3c-0491-21b1-65fc-131913d1e116.png)

### PawnのBP

![スクリーンショット 2022-07-22 163506 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/4dee0c34-108c-b5e6-1f6d-f370cfb8913c.png)

### 参考サイト

[Unreal Engine 4.25 でアクター（物体、オブジェクト）をマウスで操作するプログラムを書く - Qiita](https://qiita.com/mml/items/ce2433d94b5ee497b7b8#%E3%83%9E%E3%82%A6%E3%82%B9%E3%82%A4%E3%83%99%E3[…]%AF%E3%83%A9%E3%82%B9%E3%81%AE%E4%BD%9C%E6%88%90)
AccessのVBAで外部ファイル実行（エクセル開いたりバッチファイルをキックしたり）

# やり方

```vb:サンプルコード
With CreateObject("Shell.Application")
    .ShellExecute "C:\Users\syamiko\waruindayo.xlsx"
End With
```

# 存在しない外部ファイルを指定した場合

例外。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9682766c-89a4-bc3b-89e7-6210926c7d80.png)

# 蛇足

サクッと実装するなら ```With``` と ```CreateObject``` 使うのが楽かな～。
（変数作らなくていいし、参照設定で何かを追加する必要無いし）

その代わりコンパイルチェックができないから注意。

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1865
Microsoft Access for Microsoft 365 MSO (バージョン 2206 ビルド 16.0.15330.20260) 32 ビット
基本情報技術者試験を勉強するメリット

# 概要
先日、座談会で資格の話になりました。ある方が基本情報技術者試験を勉強するメリットについて説明くださいました。私はその説明に感動し、この感動を共有したいと思い本記事を投稿します。

以下のような人が読むと良いかもしれません。

基本情報を取得する理由、意義を見出させない人
自分の専門分野については自信があるが、ほかの分野のエンジニアと話をするのが不得意な人

# メリット　別分野のエンジニアとコミュニケーションする手段として有用
基本情報で学べる知識はコミュニケーションの手段として有用です。
たった一つの資格を取るだけで分野の違うエンジニアと意思疎通しやすくなるから基本情報はコスパが良いと思います。
下図で言うと仕事力の３要素の内共通能力に相当すると考えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/77f45094-0356-3515-6738-c4dbd193d8f4.png)

引用元：http://rasti.jp/concept/syakaijinkisoryoku.html


これをwebエンジニア界隈で適用すると以下図になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/85e5a535-66e7-f015-52c9-eb37814e2c33.png)


※バックエンドエンジニアが中心になっているかというと私が今バックエンドエンジニアの仕事を探してるからです。

専門能力が高くても、共通能力が低かったらそこがボトルネックになります。もったいないと思います。
基本情報の知識で全て解決できるとは思えないですけど、適切に使えば実務で役に立つ知識だと考えます。

具体的には基本的な単語の確認し合いとかスムーズにできるといった改善ができると思います。
別に大したロスではないのですが、塵に積もると大きな工数になると思うので地味に効果的だと私は考えます。

# デメリット　専門スキルの習得としては不十分
基本情報技術者は汎用性が高すぎて専門スキルの習得には物足りないと感じました。

私に限った話をします。
私はそもそも専門スキル、知見が足りてないです。コミュニケーションの目的は専門スキル同士を少ない手間でつなげることが目的だと思います。専門スキルが貧弱な私はつなげようがないと思います。フレームワークの公式ドキュメント、自分の分野に対応するソフトウェア工学の本を読み漁った方が自分の力になると感じました。
重要性はわかるんですけど、ついつい目先の課題を取り組んじゃうですよね…

私は全体的にできることが少ない素寒貧求職者なので当分は専門能力を高めたいですね。

# まとめ
ある程度、実務経験積んで他分野のエンジニアのことをざっくり勉強したい人は基本情報は良いかもしれないですね。
Typescriptで作成された既存のプロジェクトにWebpackを追加して、`UMD`形式で配布できるようにする

## １．Webpack のインストール

```sh
npm i -D webpack webpack-cli ts-loader
```

※ `ts-loader` は、Typescript を Webpack で処理するために必要なプラグインです。

## ２．`tsconfig.umd.json` の追加

UMD形式で出力する場合の、typescript設定ファイルを追加します。

:::note warn
`"extends": "."`は、同一ディレクトリにある`tsconfig.json`の継承を意味します。
:::

```json
{
  "extends": ".",
  "compilerOptions": {
    "module": "ESNext"
  },
  "exclude": ["node_modules", "dist", "src/**/__tests__/*"]
}
```

## ３．`webpack.config.js` の追加

**monorepo**(npm workspaces) を使用している場合、追加するディレクトリはパッケージの直下です。
例えば、パッケージが `/<rootDir>/packages/a` の場合、ファイルは `/<rootDir>/packages/a/webpack.config.js` となります。

```js
const path = require('path'); // eslint-disable-line

module.exports = {
  mode: 'production',
  entry: './src/index.ts',
  output: {
    path: path.resolve(__dirname, 'dist/umd'),
    filename: 'index.js',
    library: 'conditionals',
    libraryTarget: 'umd',
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: '/node_modules/',
        use: {
          loader: 'ts-loader',
          options: {
            configFile: 'tsconfig.umd.json',
          },
        },
      },
    ],
  },
  resolve: {
    extensions: ['.ts', '.js'],
  },
};
```

## ４．`package.json` の編集

**monorepo**(npm workspaces) を使用している場合、編集するのはパッケージ直下のファイルです。

```json
{
  ...,
  "scripts": {
    ...,
    "build:umd": "webpack", // 追加
    ...
  },
  ...
}
```
WSL2がSymentec EndPoint Protectionを通過できるようにする

社内PCでWSL2を動かすと、PCに入っているSymentec EndPoint ProtectionがWSL2からの通信をブロックしてしまいます。
これの回避方法。

ネットワークとホストのエクスプロイト緩和機能
　　↓
ファイアウォールルールの設定...
　　↓
追加...
　　↓
全般タブで
　このトラフィックを許可する
　ネットワークアダプタとしてHyper V・・・を選択
　名前はてきとうに
　　↓
OK
　　↓
ルールは一番下でもOK

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726391/70d16350-ab7f-7c74-48c8-ba09e3c9e061.jpeg)
【AWS】CAによるプライベート証明書を発行する

# 要件
プライベート証明書をACMのPCA（プライベート認証局）で発行し、CSRを利用して証明書を署名したいです。

# 前提
ACMのPCAを作成すること。
下記のコンソール画面からPCAを作成する。ただし、CAは30日間無料トライアル後400$/月の費用が発生する。かつ証明書１つにつき0.75＄かかります。
https://ap-northeast-1.console.aws.amazon.com/acm-pca/home

# 証明書発行
- IssueCertificate コマンドで証明書を発行する
- certificate-authority-arnはアカウント情報
- certificate-authorityはPCAのID
- csrはCSRファイルのパス
- validityは有効期間

```bash
aws acm-pca issue-certificate \
--certificate-authority-arn arn:aws:acm-pca:region:account:\
certificate-authority/12345678-1234-1234-1234-123456789012 \
--csr fileb://C:\cert_1.csr \
--signing-algorithm "SHA256WITHRSA" \
--validity Value=365,Type="DAYS" \
--idempotency-token 1234 
```
発行された証明書の ARN が返されます。
```bash
{
  "CertificateArn": "arn:aws:acm-pca:region:account:\
    certificate-authority/12345678-1234-1234-1234-123456789012/certificate/a2b95975ec6e1cd85a21c2104c5be129"
}
```
# 発行した証明書を取得する
- get-certificate コマンドで証明書を取得する
- certificate-authority-arnはアカウント情報
- certificate-arnは上記発行したARN

```bash
aws acm-pca get-certificate \
--certificate-authority-arn arn:aws:acm-pca:region:account:\
certificate-authority/12345678-1234-1234-1234-123456789012 \
--certificate-arn arn:aws:acm-pca:region:account:\
certificate-authority/12345678-1234-1234-1234-123456789012/\
certificate/6707447683a9b7f4055627ffd55cebcc \
--output text 
```

取得した証明書は下記のとなります。
~~~
-----BEGIN CERTIFICATE-----
...Base64-encoded certificate...
-----END CERTIFICATE----
-----BEGIN CERTIFICATE-----
...Base64-encoded certificate...
-----END CERTIFICATE----
-----BEGIN CERTIFICATE-----
...Base64-encoded certificate...
-----END CERTIFICATE----
~~~

## opensslで証明書を確認
opensslで証明書を確認できます。
~~~
openssl x509 -in cert.pem -text -noout
~~~

# 発行した証明書を失効する
- revoke-certificate コマンドで証明書を取得する
- certificate-authority-arnはアカウント情報
- certificate-serialは証明書のSerial Number(上記のopensslで確認できます)
- revocation-reasonは失効理由

```bash
aws acm-pca revoke-certificate \
--certificate-authority-arn arn:aws:acm-pca:region:account:\
certificate-authority/12345678-1234-1234-1234-123456789012 \ 
--certificate-serial 67:07:44:76:83:a9:b7:f4:05:56:27:ff:d5:5c:eb:cc \ 
--revocation-reason "KEY_COMPROMISE" 
```

# 証明書の管理
CAのコンソール画面からアクションボタンをクリックし、監査報告書の生成をクリックして頂けば、報告書を生成できます。そこに証明書の有効期限などの詳細を確認できます。

ACM プライベート CA から直接証明書を発行し、証明書の管理に ACM を使わず、ご自身でキーと証明書を管理する場合、ACM は証明書を更新しません。これらのプライベート証明書の更新とデプロイは、ご自身で行ってください。

プライベート CA から直接証明書を発行いただいた場合、更新の必要があるため、更新に伴い再度 IssueCertificate を実行いただければと思います。

# 参考
AWS CA費用

https://aws.amazon.com/jp/certificate-manager/pricing/

プライベートエンドエンティティ証明書の発行

https://docs.aws.amazon.com/ja_jp/acm-pca/latest/userguide/PcaIssueCert.html

更新とデプロイの管理

https://aws.amazon.com/jp/certificate-manager/faqs/#Managed_Renewal_and_Deployment