実は知らなかった細かいこと(備忘)

なんとなくで理解していて、実はしっかり分かってなかったモノたち。
お恥ずかしい内容のオンパレードなので同僚には見せられない。

USB3.0 = USB 3.1 Gen 1 = USB 3.2 Gen 1x1

2.0の次はとにかく「3」しかない、というざっくり理解は間違ってはなかったようですが、コンマ以降の記述があるやつは何なんだろうと思ってはいました。
こちらは理論値が5Gbps。(実効値はだいたい1Gbps前後っぽい)
2017年似登場した「3.2」の表記で記載すると「USB 3.2 Gen 1x1」にあたるということらしい。

USB 3.1 Gen2 = USB3.2 Gen 2x1

「USB 3.1 Gen 2」というのは、Gen1の2倍の速度が出るらしい(10Gbps)ですが、規格というより仕様の違いとして表記される事が多いようです。
で、2017年に登場した「3.2」の表記で記載すると「USB3.2 Gen 2x1」にあたるということらしい。
こちらのページの図がめちゃくちゃわかりやすい↓
BTO特集:3分で学ぶ豆知識「USB3.2 Gen1って?」編

外付けHDDとNASの違い

  • 外付けHDD = 外に付けるHDD/SSD(基本的にLANポートが無い)
  • NAS = LANポート(TCP/IP)で外につけるHDD/SSD

え~~っ、知らなかった。
いや、確かに手元の1ディスクの外付けHDDとかは「NAS」とは言わないし、でも「自宅の外からでも写真投げ入れられるようにしておきたいな」と思ったらNAS設置するかなーとか思ってはいたので、なんとなく、個人レベルでは結果的には正しい解釈をしていたのですが、複数ディスクの大きい法人向け「外付けHDD」と、「NAS」のなにが違うんやって実は分かってませんでした。
Nは「ネットワーク」のNだろうと思ってはいましたが、別にインターネットにのっけなくてもネットワークはネットワークなので、具体的に「TCP/IPでの接続」を前提としたものだと言われてなるほどやっと理解しました。

SAN・SCSI・FC・iSCSI

SAN=Storage Area Network
「サン」って「Sun microsystems」を思い浮かべてしまうアプリケーション世代。ハードの世界ではストレージ構成を「SAN」というのか。

さらに恥ずかしながら「FC」って「ファンクラブ」にしか見えない…。こちらはFibre Channel の略だそうです。(しかも英英語)
元々はSCSIスカジー)という接続方式でストレージ間のやり取りをしていたけど、それが物理的にもどんくさい仕様だったらしく、SCSI対応もできる新しい規格としてFCが出てきたらしい。(ファミコンソフト並にピンがめちゃくちゃついているお煎餅みたいなコネクタのあれ。そういえば見たことある。ストレージ共有に限らず、いわゆる周辺機器接続に多く使われたものだったみたい。)

ところがFCはFCで専用のスイッチ、アダプタ、ケーブルが必要で、これはそこまで安価じゃないのと揃えるのが面倒なのもあって、そこまでパーッと普及しなかったと。(2009年時点@ASCI)
それで出てきたのがiSCSI(アイ・スカジー)。このアイは「Internet」ということで、従来のSCSIの仕組みをTCP/IP上で使える。
FCと違って専用線じゃない点は遅くなる可能性があるけど、既存のLANに乗っけられるのですごく楽だよねと。

ここの話は↓ さすがASCI、記事は2009年のものなので状況は変わってきていると思うけど、わかりやすかった。
ascii.jp

git --orphan

なんそれかっこいい。
いや、環境によって変わる設定ファイルをどうやってgitで管理しようかなぁと思っていたところヒットした記事で、「--orphan」というのを知りました。
Git - gitでmasterに含めたくないファイル|teratail

git checkout --orphan すると、履歴を持たない、いわゆる本当にただのファイル群としてワークツリーが分離されるらしい。
一応ブランチなので、そのままブランチを切れば全ファイル登録されるんだけど、「履歴を持ちたくない」もの以外は全部削除してコミットすればおk.

なるほどこれをすれば、マージしたときに上書きされたりしないということですよね。

まあ、環境ごとの設定値なんてそもそもファイル自体に分岐を書いておけばええやんけという程度の話なのですが、用途は色々と考えられるので覚えておこうと思います。

MySQL CLI基本コマンド

しばらく触らないとスグ忘れるのでメモ。
ls -la すらたまに忘れるから。さすがに嘘だけど。viのコマンドはたまに忘れる。人間だもの。

ログイン

mysql -u root -p DB名

DB名打たなくてもおk.
打たない場合はDBを指定する必要があるのでログイン後、以下で確認&選択。

DB一覧
SHOW databases;
DB選択
USE DB名;

テーブル一覧

SHOW tables;


あとは普通にselect。
SQL文だけは昔クソほど打ったのでギリギリ忘れないらしい。

中央リポジトリ(bareリポジトリ)の作り方2パターンを理解する

絶賛、git思い出し中。

たしか大事だった気がする、リポジトリの共有に関連するポイントをまとめておきます。

中央リポジトリは「--bare」で作成

中央リポジトリを作成する(init)ときとか、既存のリポジトリを中央リポジトリとしてクローンする(clone)ときとかに「--bare」を使う。
ちなみにbareレポジトリは「xxx.git」という拡張子で記載するのが基本ルール。

bare

--bareオプションは、以下のヘルプのとおり、ワーキングディレクトリ(実際のファイル群)を持たないリポジトリとして作成できる。

Treat the repository as a bare repository. If GIT_DIR environment is not set, it is set to the current working directory.


そして、中央リポジトリを作成するとき、然るべきユーザがアクセスできるよう「--shared」というオプションを使うのだが、これがちょっと注意。

新規で「init」するときは「--shared」する

shared

init の --sharedオプションは、リポジトリに対するグループ書き込みパーミッションを自動的に追加してくれる。
これは実際には「When specified, the config variable "core.sharedRepository" is set so that files and directories under $GIT_DIR are created with the requested permissions.」ということで、これ↓を実行しているのと同じ。

$ git config core.sharedrepository true

手順

  1. git init --bare --shared
  2. 作業場所に「clone」
  3. first commit
  4. 中央リポジトリに「push -f」

※ブランチが存在しないところにfirst commitを投げることになるので、--force での強制pushが必要

既存リポジトリから「clone」するときは「--shared」しない(ほうが無難)

initと同じテンションで clone --shared していたことがあるのだけど、これはヘルプで「危険だからよく分かってない人は使うな」とNOTEされている。
clone の --shared は、「クローン元がローカルにある場合に、クローン元のオブジェクトを共有する(から、クローン先は独自のオブジェクトを持たずにいける)」という意味らしい。

そもそもclone時に、ソースリポジトリ(クローン元)がファイル形式(ローカルのパス)の場合は、「--local」オプションが自動で適用される。
この「--local」は、オブジェクトがハードリンクになってディスクの節約になるという動きをしてくれる。
ハードリンクは「ソースリポジトリのURL」ではなくそれが指している「実体」にアクセスするので、ということは、クローン先で変更をかけたらクローン元でも反映されているということ(だと思う)。バックアップなど通常のコピーを持ちたい場合は「--no-hardlinks」を使う。

「--shared」というのは、これを「.git/objects/info/alternates」というのを使ってハードリンクではない方法(シンボリックみたいなものなのかな?)でソースリポジトリのオブジェクトを参照してくれる。
ただし、この状態でソースリポジトリでブランチを消したりすると、参照が壊れたり、クローン先のリポジトリが破壊されたりすることがあるらしい。
いまいち仕組みがよくわからないけど、つまり「clone --shared」とするのは「閲覧用」ということになるのかしら?

手順

そういうわけで、既存リポジトリからcloneして中央リポジトリを作成する時は、こういう手順になる。

  1. 既存リポジトリに「git clone --bare」
  2. 作成した.gitファイル内で「git init --bare --shared」

これが公式のbooksに書いてあるやり方。

もしくは、2. の代わりに以下を行うというのも大丈夫だと思う。
現場では動作確認をしたのがこちらのやり方だったので、こっちでやってた。

$ git config core.sharedrepository true
$ chmod -R g+ws hooks
$ chmod -R g+ws info
$ chmod -R g+ws objects
$ chmod -R g+ws refs

gitヘルプ

gitはヘルプがめっちゃ優秀なので、ググって野良記事を探してもいいけど信頼すべきはこっち。

git-scm.com

git-scm.com

Git Bashでgithubに接続できるようにする(SSH)

1,SSHの鍵を作成する

Git Bashを立ち上げて、RSAキーペア(公開鍵と秘密鍵)を作る。
-b:長さ。デフォルトは2048(256バイト)だけど推奨は4096(512バイト)みたい。
-C:鍵の中に入るコメント。無くてもOKだけど、PCが識別できるコメントを入れておく。

$ ssh-keygen -t rsa -b 4096 -C "○○○○○"

どこに作るか聞かれる。
githubの鍵だということが分かるようにファイル名だけ変えておく。

Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/user/.ssh/id_rsa): /c/Users/user/.ssh/id_rsa_github

パスワードを2回聞かれるので入力すると、キーペアができる。(id_rsa_githubとid_rsa_github.pub)
あたりまえだけどgithubのログインパスワードとかとは全く関係ない。

Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/user/.ssh/id_rsa_github
Your public key has been saved in /c/Users/user/.ssh/id_rsa_github.pub
The key fingerprint is:
SHA256:(略) ○○○○○
The key's randomart image is:
+---[RSA 4096]----+
(略)
+----[SHA256]-----+

Linuxとかの場合は、安全のためにここで秘密鍵(/c/Users/user/.ssh/id_rsa_github)のパーミッションを600にchmodするのがセオリーだが、今回はログインパス付きのWindowアカウント上なので特に何もしません。(chmodしても変わらない)

それと、公開鍵と秘密鍵が同じ.ssh/に配置された状態になるので、なんとなく公開鍵は別Dirに移してアーカイブにしておきます。

2,公開鍵をgithubに登録する

  1. githubにログイン
  2. 右上のアカウントメニュー > Settings
  3. 左メニューの「SSH and GPG keys」 > New SSH Key
  4. ローカルに作った「id_rsa_github.pub」をエディタで開いてコピーし、「Key」に貼り付ける
  5. 「Title」はPCを識別できる名前をつける(何でもOK)

3,sshのconfigに追記する

これやらなくてもsshコマンドで接続できますが、面倒くさいのでconfigにエイリアス(ショートカット?)を追加。

$ vim ~/.ssh/config

Userはgithubのアカウントとか関係なく全員「git」。
IdentityFileは作成した秘密鍵を指定する。

Host github
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa_github

4,Git Bashから接続する

これで接続できるようになる。

$ ssh github

パスワードを聞かれるので、上記でSSH鍵を作った時に入力したパスを入力。
「You've successfully authenticated, but GitHub does not provide shell access.」って表示されれば成功です。

やってることは以下と同じ。

$ ssh -i ~/.ssh/id_rsa_github git@github.com

Git 覚書(ローカルで自分のためだけのリポジトリを作る)

Git、触ってないとすっかり忘れてしまうこともありまして、忘れっぷりにビビったのでメモっておきます。

GitHubからcloneしてきて不特定大多数もしくは複数人チームでソースを共有する、という場合ではなく、ローカルPCで自分用にソース管理する、という前提。

プロジェクトを開始する

1,管理したい任意のディレクトリの1階層上で「Git Bash Here」をクリック
2,git init
3,コンフィグを確認(git config -l)

→ 「user.name」と「user.email」が入っているかを確認
→ 無ければ追加する
→ リスト表示は「q」でquit出来る

※user.emailとuser.nameはPCローカルの.gitconfigに記述される

4,エイリアスを追加する

追加するのはプロジェクトの/.git/config でもいいしルートの.gitconfigでもいい。
だいたいいつもこんな感じ。

[Alias]
	s = status
	f = fetch
	aa = !git add . && git status

	# 今いるブランチ名のみ表示
	b = symbolic-ref --short HEAD

	# リモートトラッキングブランチも含めてブランチをすべて表示
	br = branch -a

	# checkout
	co = checkout

	# 1つ前のコミットに追加する
	join = commit --amend --no-edit

	# 未ステージングと最新コミットの差分
	d = diff --word-diff

	# 最新コミットと1つ前のコミットとの差分
	dd = diff --word-diff HEAD^

	# ステージング済のものと最新コミットの差分
	dic = diff --cached --word-diff

	# origin/masterと自分の差分ファイルを確認する
	gap = !git fetch && git diff --compact-summary origin/master @{0}

	# origin/masterと自分の差分ファイルを確認する
	gaps = diff --word-diff origin/master @{0}

	# 共有リポジトリ(親)と自分の差分ファイルを確認する
	dry = !git fetch && git diff --compact-summary @{0} @{u}

	# 共有リポジトリ(親)と自分の差分ファイルを確認する
	drys = diff --word-diff @{0} @{u}

	# デプロイ時のmerge は --no-ff
	mg = merge --no-ff --no-commit

	# 特定のファイルをアンステージする
	uns = rm --cached

	# ステージングをすべて未ステージングに
	unstage = reset HEAD

	# 後ろに指定したファイルの編集をなかったことにする
	discard = checkout --

	#すべての編集をなかったことにする(ステージングされているものはそのまま)
	disall = checkout -- .

	# pushしていないコミットをまとめる
	wad = reset --soft @{u}

	# 1つ前のログの状態に戻る
	back = reset --soft HEAD^

	# 最新コミットで強制上書きする(最新コミットの状態に戻す)
	clear = reset --hard HEAD

	# 現在のブランチをログを含めて共有リポジトリですべて強制上書きする
	# (未pushのローカルコミットはなかったことに)
	refresh = !git fetch && git reset --hard @{u} && git gc

	# 後ろに指定したファイルのログ(差分)を表示
	fdiff = log --word-diff -p

	# 後ろに指定したファイルの行ごとの最終ハッシュとコミッターを表示(行選択して「,」で遡れる.qで戻る)
	line = !tig blame -M

	# 最新コミットの編集ファイル一覧
	clist = diff --name-status HEAD^

	# 現在地のハッシュ(短縮版)
	hash = rev-parse --short HEAD

	# 現在地のハッシュ(ロング版)
	last = log -1 HEAD --format=format:'%C(yellow bold)%H'

	# 最新のログ20件を見やすく
	ll = log --graph --oneline --decorate=short --date=format:'%Y-%m-%d %H:%M:%S' -20 --format=format:'%C(yellow)%h%C(reset) %C(green)[%ad]%C(reset) %s %C(cyan) %an%C(reset) %C(auto)%d%C(reset)'

	# 最新のログ20件を、リモートトラッキングブランチを含むすべてのブランチで表示
	lla = log --graph --oneline --decorate=short --all --date=format:'%Y-%m-%d %H:%M:%S' -20 --format=format:'%C(yellow)%h%C(reset) %C(green)[%ad]%C(reset) %s %C(cyan) %an%C(reset) %C(auto)%d%C(reset)'

	# 今いるディレクトリのファイルが最後に更新されたのはいつか の一覧
	files = !cd ${GIT_PREFIX:-.} && git ls-tree -z --name-only HEAD xargs -0 -n1 -I@ -- git log -1 --pretty=format:'%C(green)%ai%Creset %C(yellow)%h%Creset @ %C(cyan)(%ar)%Creset %C(red)<%an>%Creset' -- @
5,ホワイトリストを書く

→ .gitignoreを作成。
→ たぶん画像は毎回ハズすのでこんな感じ

*.jpg
*.png
*.jpeg
*.gif
*.svg
6,ホワイトリストだけコミットする

最初にファイルコミットしないこと。

  git add .gitignore
  git status
  git commit -m "First commit"
  git log

※最初にファイルコミットしないのは、「最初のコミット」はツリーをいじれない(いじりづらい)ため。

7,すべてコミットする
  git add .
  git status (gitignoreが活きているかを確認する)
  git commit -m "全部コミット"

ModuleNotFoundError: No module named XXX; XXX is not a package[Python]

Pythonを少し勉強中です。
まさかのアホエラーをかましたのでメモ。

何が起きたのか

QRコードを吐くという簡単な練習問題を実装したのですが、これのためにサードパーティ製パッケージの「qrcode」というのを使ったわけです。
pipでインストールし…

pip install qrcode

コード内ではimportを宣言。

import qrcode


何もおかしなところはありませんよね……。
でもこれを実行するとこう言われてしまい、import自体がうまく行かない。

ModuleNotFoundError: No module named qrcode; qrcode is not a package

原因

ググると、「Pythonは複数インストール可能なので、そもそも実行されているPythonそのものが、パッケージをインストールしたのと別のPythonなのではないか」説が最も多くヒットするのですが、どう調べてもインストールされているpythonは1つで、ちゃんと同一のpathを指しています。

IDEが原因かなぁと思い、ターミナルの対話モードで「import qrcode」とタイプすると、エラー文は…

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\xxx\Desktop\work\qrcode.py", line 2, in <module>
    import qrcode.image.svg
ModuleNotFoundError: No module named 'qrcode.image'; 'qrcode' is not a package

ん????
なんで実行ファイルの方のエラーが出るんだ…… 


_人人人人人人人人人人人人人人人人人人人_
> パッケージ名と実行ファイル名が一緒 <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄


ファイル名を別名にしたらすんなり通りました…。
アホなことしないように気をつけよう!

~ 終 ~

OCR結果が一定サイズ以上でエラー:record_overflow

HeartCore RoboでOCR(エンジンはGoogleVision)していたところ、特定のサイズ以上の範囲の読み込みで「record_overflow」というエラーが出たのでメモ。

エラー

f:id:hiro-29:20200312145818p:plain
java-error

Received fatal alert: record_overflow

4~5行で130文字くらいまでは読み込みできていたのに、150文字くらいでこのエラーが出現。
こういうエラー表示って何のエラーなのか分かりづらいよね…。

ということで恐らくこれ。Javaのバグだったっぽい。
github.com
bugs.openjdk.java.net

Javaのバージョンが12.0だったので、恐らくこれに該当してたと思われます。

アプデ

本家からDLして、実行中のアプリを全部落としてからインスコ
環境変数のPathを修正して、再起動。
www.oracle.com

無事に150文字以上のOCRが続行できました。