OmniAICreator/Qiita-1.07M huggingface dataset:
【python3.6.4】ファイルを読み込む

ファイルを読み込む方法を記事にします。pythonのバージョンは、3.6.4になります。
説明に使用するテキストファイルになります。

```test.txt
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
111111111111111111111111111111111111111111111111111111111111
222222222222222222222222222222222222222222222222222222222222
333333333333333333333333333333333333333333333333333333333333
ああああああああああああああああああああああああああああああ
いいいいいいいいいいいいいいいいいいいいいいいいいいいいいい
うううううううううううううううううううううううううううううう
```

今回、test.txtはDドライブのpythonディレクトリに存在します。
コマンドプロンプトを起動して、d:を入力すると、Dドライブに移動します。

```MS-DOS
C:\Users\test>d:
D:\>
```

次にpythonディレクトリに移動します。

```MS-DOS
D:\>cd python
D:\python>
```

pythonを起動します。

```MS-DOS
D:\python>python
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

pythonプログラムを入力します。

```MS-DOS

>>> f = open ('D:/python/test.txt')
>>> print(f.read())
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
111111111111111111111111111111111111111111111111111111111111
222222222222222222222222222222222222222222222222222222222222
333333333333333333333333333333333333333333333333333333333333
ああああああああああああああああああああああああああああああ
いいいいいいいいいいいいいいいいいいいいいいいいいいいいいい
うううううううううううううううううううううううううううううう

>>> f.close()
>>> exit()

```
Python 辞書型(dictionary)　まとめ

#はじめに
辞書型についてうまくまとめられた記事が見当たらなかったので自分用にまとめてみました。
AtcoderをPython使ってやってます。

#初期化について


```python:空の辞書型
>>> d = {}
>>> d
{}
```

`{string: int, string: string, int: int}` など色々入れれる

```python:値を入れて初期化
>>> d = {'x': 1, 'y': 'yyyy', 1: 1000, 'list': [10, 20]}
>>> d
{'x': 1, 'y': 'yyyy', 1: 1000}
```

```python:dictメソッドを使って
>>> d = dict(a=10, b=20)
>>> d
{'a': 10, 'b': 20}
```

# 値の追加について

```python:代入
>>> d={}
>>> d['x'] = 10
>>> d
{'x': 10}
```

```python:setdefaultメソッド
>>> d = {}
>>> d.setdefault('x', 1000)
1000
>>> d
{'x': 1000}

>>> d.setdefault('x', 2000)
1000
>>> d
{'x': 1000}
```

# 便利なメソッド

### キー、バリューの取り出し
```python:keys()
>>> d = {'x': 10, 'y': 20}
>>> d.keys()
dict_keys(['x', 'y'])
```

```python:values()
>>> d = {'x': 10, 'y': 20}
>>> d.values()
dict_values([10, 20])
```

###要素をオーバーライド
```python:update()
>>> d = {'x': 10, 'y': 20}
>>> d2 = {'x': 30, 'i': 100}
>>> d
{'x': 10, 'y': 20}
>>> d2
{'x': 30, 'i': 100}

>>> d.update(d2)
>>> d
{'x': 30, 'y': 20, 'i': 100}
```

###要素の取得
```python:get()
>>> d = {'x': 10, 'y': 20}
>>> d['x']
10
>>> d.get('x')
10

# keyにないものを取り出そうとするとエラーになる
>>> d['z']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'z'

# getメソッドを使うとNoneが返ってくる
>>> r = d.get('z')
>>> type(r)
<class 'NoneType'>
```

###要素を取り出しつつ削除
```python:pop()
>>> d = {'x': 10, 'y': 20}
>>> d.pop('x')
10
>>> d
{'y': 20}
```

```python:del
>>> d = {'x': 10, 'y': 20, 'z': 30}
>>> del d['x']
>>> d
{'y': 20, 'z': 30}
>>> del d
>>> d
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'd' is not defined
```
```python:辞書を空にする
>>> d = {'x': 10, 'y': 20}
>>> d
{'x': 10, 'y': 20}
>>> d.clear()
>>> d
{}
```
###キーがあるか判定
```python:in
>>> d = {'x': 10, 'y': 20}
>>> d
{'x': 10, 'y': 20}
>>> 'x' in d
True
>>> 'z' in d
False
```
###コピー


```python:変数はオブジェクトへの参照を保持するため、変数代入ではコピーができない
>>> d = {'x': 10}
>>> d2 = d
>>> d2['x'] = 20
>>> d
{'x': 20}
>>> d2
{'x': 20}
```

```py:コピーメソッドを使う
>>> d = {'x': 10}
>>> d2 = d.copy()
>>> d2['x'] = 20
>>> d
{'x': 10}
>>> d2
{'x': 20}
```
###ソートメソッド
```python:sorted
>>> d = {'z': 10, 'y': 20, 'x': 30}
>>> sorted(d.items())
[('x', 30), ('y', 20), ('z', 10)]
>>> d
{'z': 10, 'y': 20, 'x': 30}
>>> d = sorted(d.items())
>>> d
[('x', 30), ('y', 20), ('z', 10)]
```
Python exeファイル作成

自分メモにて、まとまっていませんが。。

◆目的
anaconda環境をいれていない人でもpythonで作ったプログラムを実行できるようにするため
exeファイル作成方法(pyinstaller.exe使用) 

◆環境
windows10
anaconda3
python3.7.3

◆関連
・exeファイル作成ツールとしては、pyinstaller と　py2exeがある。また cx-Freezeもある。
　→　pyinstaller は使い方が簡単そう。
　→　py2exeの方が、動作が速いらしいが、2016年時点では python3.4までの対応（現在は対応上がった？？）
　　 python3.5以上だとインストールできても、実行クラッシュするらしい。
・ライセンスについて　作成したexe配布は商用利用でも可能そうだが今後調べる

# 処理手順： condaでインストールする場合
手順1 事前準備 proxy設定する　https://qiita.com/taiko1/items/19690ba49c1a0478159f
手順2 事前準備 管理者として anaconda prompt を起動する
手順3 conda -installする

```
conda install pypiwin32
conda install pyinstaller
```
↑ pypiwin32 は不要かも。
　pypiwin32 のインストール失敗するようならここはスキップして pyinstallerだけすればいいかも。
　（pyinstaller関連ファイルとして、pypiwin32も含めて自動インストールされるかもしれないので）


# 処理手順： pipでインストールする場合
anaconda環境では, pip installしないのが望ましいが
パッケージがみつからない場合は下記方法でした

１. pyinstaller.exe のインストール
　　コマンドプロンプト（anaconda commandPrompt） で下記2つのコマンドを実行

```
pip install pypiwin32  --proxy=http://proxy01.xx.co.jp:8080
pip install pyinstaller --proxy=http://proxy01.xx.co.jp:8080
```
   　※ ↑では--proxy=プロキシサーバーアドレス　指定したが、PC環境によっては不要かも
　　※1回目　pip install pypiwin32なしで実行 pyinstaller実行しようとすると固まってしまって完了しなかった。
　　※2回目　アプリから。。anaconda Navigator の root環境でインストールしてみた。　依存パッケージのいくつかは入ったみたいだが、結局完了できなかった。
　　※3回目　再度コマンドプロンプト anaconda commandPrompt で上のコマンド実行して成功
　　(①pip install pypiwin32が効いたはず）（2回目で依存パッケージが入ったのもよかった？？）

2. テストプログラムでの実行

HelloWorld.py
print('Hello World')
input('Press Enter Key To Exit')

コマンドプロンプト（anaconda commandPrompt） で下記コマンドを実行
pyinstaller.exe HelloWorld.py 

正常完了すると、dist フォルダ下に　HelloWorld.exeファイルができる。

※参考：http://blackchip.hateblo.jp/entry/2016/12/19/225503
※参考：https://qiita.com/ymdymd/items/f9f5587f0f3128285e25
方法として　--onefileオプションもあり, 1パッケージにまとめられ
ファイル容量を半分ほどにできる利点あり。
実行方法は --onefileオプションをつけ、さらにbuild.batch実行。
　pyinstaller HelloWorld.py --onefile
　↓作成された下記を実行
　build.bat
スロットコンテンツの書き方メモ

3連休だしVueを1から初めて遊んでみようと思った。
その中でスロットコンテンツを使ってコンポーネントの差し替えを行おうとした。
参考書には正しい例しか載っていないので、実験がてら試したことの考察

Vueの定義

```JavaScript:vue01.vue
var headerTemplate = `
  <div id="test">
    <slot name="header">No Title</slot>
  </div>  
`
Vue.component('page-header', {
  template: contentTemplate
})
```

失敗例

```html:index01.html
  <page-header>
    <span><div slot="header">hoge</div></span>
  </page-header>
```
```html
<div id="test">No Title</div>
```

成功例

```html:index02.html
  <page-header>
    <span slot="header"><div>hoge</div></span>
  </page-header>
```
```html

<div id="test"><span><div>hoge</div></span></div>
```

***考察***
挙動から読み取れる限り下記のようなロジックがありそう。
① コンポーネントタグはVueで定義したコンポーネントを呼び出すだけで、その間にdiv等のタグを含めてもロストしてしまい、テンプレートがそのまま表示される。
② スロットコンテンツを使えば、コンポーネントタグ内の情報をVue側に渡せるので、それはロストせずテンプレートへの上書きを行う。

失敗例を見る限り、コンポーネントタグの最初のタグがslot属性を持っていなければ、その下のネストのタグがslotを持っていても②のロジックで判断されず、システム側がコンポーネントタグ配下のタグは①のロジックで扱っていいものだと認識して、slotをロストさせてしまっているのではないだろうか。
\# わざわざ失敗例のようなタグ構成にする必要は何もないとは思いますが…

Vue有識者の方、もしよろしければアドバイスをいただけると助かります。
Ruby on Railsの環境構築した時に出たエラーとか

# はじめに
サーバーサイドの知識があまりなかったため、Railsをなんとなーく導入してみようと思い、なんとなーく環境構築を勧めていたら、無知も相まって色々と悩んだのでメモを残しておく。今回予め、Gitlab,Redmineあたりを勉強ついでに導入しており、その関係でRails側の設定やインストール工程を一部省いたりもしたため、rubyとかbundlerとかpostgresqlとかをrailsのためにインストールし直したりはしていない。

# Railsを導入するにあたって参考にしたサイト
- [Rails on CentOS7](https://qiita.com/hys-rabbit/items/f24b930a75f7ec211d59)
- [Rails 環境をCentos7に構築](https://qiita.com/tomsyoya/items/addf78f28a63ecda82b3)

# 環境
- OS (CentOS7)
- ruby (2.4.1)
- bundler (1.17.3)
- gem (3.0.4)
- rails (5.2.3)
- postgresql (9.2.24)

# 本題

## bundler command not found: spring

```
Bundle complete! 18 Gemfile dependencies, 60 gems now installed.
Gems in the groups development and test were not installed.
Bundled gems are installed into `./vendor/bundle`
         run  bundle exec spring binstub --all
bundler: command not found: spring
Install missing gem executables with `bundle install`
```
rails new 'アプリ名' -d postgresqlを実行した時に出たエラー。
単純にspringというコマンドがなく、次の工程に進めないという話なのだけど、なぜ存在しないのかが分からなかった。
結論から言うとbundlerのconfigに問題があり、developmentとtestグループがBUNDLE_WITHOUTに設定されていたため、Gemfileの特定の行を通っていなかった。
参考URL(http://ruby.studio-kingdom.com/bundler/bundle_config/)

```:.bundle/config
---
BUNDLE_PATH: "vendor/bundle"
BUNDLE_WITHOUT: "development:test"
```
ひとまず以下の様に修正

```:.bundle/config
---
BUNDLE_PATH: "vendor/bundle"
BUNDLE_WITHOUT: "test"
```
これでspringコマンド含め、諸々インストールされた。

## Could not find a JavaScript runtime
JSのランタイムがないとかなんとか。nodejsインストールで解決した。
参考URL(http://djandjan.hateblo.jp/entry/2018/07/25/224929)

## Address already in use
正しくは 

```
Address already in use - bind(2) for "127.0.0.1" port 3000 (Errno::EADDRINUSE) 
```
と出力されていた。
多分3000番ポートが既に使用されているので、ポートの使用状況を lsof -i:3000 で確認してみたら、どうやらGitlabで使われてるっぽい...のでRailsのポートを変更することにした。
以下のコマンドでひとまず解決。

```
$ rails s -p 3001
```

Linux上ではひとまず起動したようなので、よしこれでページアクセスできるわ！と思い、ブラウザーにアドレス入力。エンターキーに渾身の力をこめてﾀｰﾝｯしたら想定していたページが表示されない。このサイトにアクセスできませんとのこと。
これについては、下のURLに詳しいことが書いてあった。
[参考URL](https://www.techscore.com/blog/2014/09/12/rails4-2beta1%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%97%e3%81%a6%e6%9c%80%e5%88%9d%e3%81%ab%e3%81%af%e3%81%be%e3%81%a3%e3%81%9f%e3%81%93%e3%81%a8/
)
結果

```
$ rails s -b 0.0.0.0 -p 3001
```
これでアクセス"は"できるようになった。

あとファイアウォールのポートの設定忘れてるとアクセスできないので注意。

## role "ユーザー名" does not exist
データベース側の設定ができておらんのでアクセスできてもページの表示ができなかった。
まずはユーザーが存在しないところから。下記URLの通りにすれば作成できた。ユーザー名はRails sを実行しているユーザー名にすればいい思う。（多分）
自分の場合はrootでやっていたので、

```
$ sudo su – postgres
$ createuser -s -r root
```
で作成は完了。
参考URL(https://kirohi.com/rails_pg_error_role_doesnotexist)

## データベースが存在しない。
下記URLの通り設定していきましょう。"Rails の設定とか"の辺りに詳しく書いてある。
データベースの名前はエラーページに表示されている通り。(\*\*\*の部分はrails new で作成したアプリの名前)
\*\*\*_development
\*\*\*_test
\*\*\*_production
[参考URL](https://qiita.com/longtime1116/items/9045717ff8607bed07fe)

# 余談
改めて記事にしてみて、アドレスの指定のところとか、そもそもDBまわりの知識があまりないとかちらほらあったので改めて調べ直したら記事にして考えを整理したいと思う。

また、もし誤った情報があれば、ご指摘いただけると幸いです。
Unityでオンラインマルチプレイなゲームを作りたい その2 環境導入

前回、オンラインゲームを楽に開発するためのエンジンを選びました。[前回の記事](https://qiita.com/koyuki2007/items/180be375eeca9108c687)
今回はそのエンジンを用いて開発する準備を行いたいと思います。
# 前提
Unityをインストールし、触った経験がある
# 環境
Unity2019.1.0f2
Monobit Unity Networking(記事作成時の最新バージョン2.7.0)
# 今回の目標
とりあえずオンラインゲームを開発できるように環境を整えます。
# 導入
#### Unityの設定
自分が使ってるUnityの設定と、念のため合わせたい人向けにとりあえず記述します。(特に合わせる必要性を感じない人は飛ばしてOKです)
1. Unityを立ち上げ、File → Build Settings → Player Settrings → Other Settingsで以下の画像の通りに設定する。
![2019_08_01_2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/a391988a-5db9-1314-e062-bb093ebb2958.jpeg)
2. File → Build Settings → Player Settrings → Resolution and Presentationで以下の画像の通りに設定する。
![2019_08_01.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/76dd8878-4337-0cf9-bc27-f095c5df8731.jpeg)
#### MUNを使用できるように準備
##### サーバーを準備
[モノビットエンジンクラウド公式マニュアル](https://web.cloud.monobitengine.com/usage?page=registration)
・こちらのサイトを参考に、アカウント登録を済ませ、サイトにログインします。
![aaaaaaaaaaaaaaaaaaaaaaaaa.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/b6b68eac-bc95-66fa-44c7-58d279c2e82f.jpeg)
・ログインするとこんな感じの物が表示されていると思うので、画像上の赤で囲っている「アプリケーションID」と「MUN リゾルバ一覧取得エンドポイント」をコピーして控えておきます。

これで、クライアントのネットワーク接続先となるサーバーの準備ができました。

##### サーバーへ接続するクライアントの準備
[MUN公式サイト](https://www.monobitengine.com/mun/#download)
・MUNの配布しているサイトへアクセスします。
![2019_08_01_3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/ddb73926-09fb-6e89-c35a-c0260178bfbb.jpeg)
・↑の画像内で黒丸で囲っているところをクリックし、MUNのアセットをダウンロードします。
・ダウンロードを終えたらUnityを立ち上げ、ダウンロードしたアセットをインポートします。

・インポートを終えたら、Assets/Monobit Unity Networking/Resources/内にある、MonobitServerSettingsをダブルクリックし
![ャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/fcffcafc-feb8-d900-55a7-674340a81e3b.jpeg)
・↑の画像の通りに設定し、赤で囲っている「Endpoint Address」と「AppID」にサーバーの準備で控えておいた「MUN リゾルバ一覧取得エンドポイント」と「アプリケーションID」を入力します。

これでクライアントの準備ができました。

##### サンプルで環境導入ができたかを確認
[RandomMatchingReconnectサンプル](http://www.monobitengine.com/doc/mun/contents/Sample/RandomMatchingReconnect.htm)
こちらを使って確認しようと思います。

1.Assets/Monobit Unity Networking/Samples/Scenes/RandomMatchingReconnect/内にある「OfflineSceneReconnect」と「OnlineSceneReconnect」をFile/BUild SettingsのScenes In Buildに追加します。
2.Buildします。
3.Buildで作成されたアプリケーションを2つ立ち上げます。
4.立ち上げたうちの片方で、CreateRoomを押します。
![gfdag.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/6c61a29d-153c-8a51-4aa6-69b94d05b841.jpeg)
5.もう片方のアプリに、roomName(1)と書いてあるボタンが表示されると思うので、それを押します。
![asdfghjkl.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/176ef823-0533-0060-2d5d-c517fe53d158.jpeg)
6.Create Roomを行った方のアプリに戻って、GameStartを押します。
![zxcvfgt.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/c7de1a62-a498-65e4-6970-f23f4f62d012.jpeg)
7.立ち上がってる二つのアプリのどちらでもいいのでユニティちゃんを動かしてみてください。
![qwxwrcx.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/428d936e-65d3-f623-40d9-5db9e19c89a7.jpeg)
もう片方で同じようにユニティちゃんが動いてるのが確認できればOKです。

以上でオンラインマルチプレイを開発する環境が整いました。
次回からは実際にゲームを作っていきたいと思います。
Raspberry Pi 3 Model b（OS:4.19）+とRPZ-IR-Sensor での赤外線受信でハマった

#概要
ラズパイの赤外線受信でハマったので、設定内容をまとめました。

#環境
・Raspberry Pi 3 Model b+
・Linux raspberrypi 4.19.58-v7+ #1245 SMP Fri Jul 12 17:25:51 BST 2019 armv7l GNU/Linux
・RPZ-IR-Sensor Rev2.0 (端子実装済 + 外付センサーセット)


#設定内容
###/etc/lirc/lirc_options.conf
このファイルでは特に問題なかった。（ホントは色々やらかしたけど）

```/etc/lirc/lirc_options.conf
[lircd]
nodaemon = False
driver = default       <=ここと
device = /dev/lirc0    <=ここを修正
output = /var/run/lirc/lircd
pidfile = /var/run/lirc/lircd.pid
plugindir = /usr/lib/arm-linux-gnueabihf/lirc/plugins
permission = 666
allow-simulate = No
repeat-max = 600

[lircmd]
uinput = False
nodaemon = False
```

###/boot/config.txt
ここでハマった。。。（ハマリポイント１）

>lircからir-keytableとir-ctlに移行
[http://themaster.asia/2019/04/16/raspi/lirc_ir-keytable_ir-ctl.html](http://themaster.asia/2019/04/16/raspi/lirc_ir-keytable_ir-ctl.html)

上記の記事のおかげで動作させることができました。ありがとうございました。　ヽ(=´▽`=)ﾉ

51行目 「dtoverlay=lirc-rpi」辺りの3行を修正

```/boot/config.txt
# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details
・
・
中略
・
・
# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi                                      <=ここをコメントにして
dtoverlay=gpio-ir,gpio_pin=4                             <=これと
dtoverlay=gpio-ir-tx,gpio_pin=13                         <=これを追加した。
・
・
下も略
```

失敗例：
・追加した2行をファイル最下部の辺りに書くのはNG。
・/dev/lirc3 とか、/dev/lirc4 とかができた場合は、他にも赤外線用の設定がある。
　色々試行錯誤した後だったので、ゴミが残っていましたｗ

#赤外線受信
ポイントは、/dev/lirc1 を使うことでした。（ハマリポイント２）

受信コマンド例：
ir-ctl --device=/dev/lirc1 -rIR_RECV

最初に赤外線を受信することができた時は、思わず声出ましたｗｗ
やよい軒メニューからPFCバランスをスクレイピング

# 概要
減量中に外食だとカロリー計算に困るので
やよい軒のメニューからカロリー、PFCバランスを取得しておく。

# 利用技術
- python3
- BeautifulSoup


# やってみた

コードを書いて

```python:
# coding: UTF-8

import urllib.request
from bs4 import BeautifulSoup
import re


# やよい軒 サバの塩焼定食
url = "https://www.yayoiken.com/menu_list/view/467"

# URLにアクセスして html取得
html = urllib.request.urlopen(url)

# htmlをBeautifulSoupでパース
soup = BeautifulSoup(html, "html.parser")

# 栄養素が入っているボックスを取得
eiyo_box = soup.find(class_='eiyo_box')

# カロリー, P, F, Cの数値を取得
eiyoso = eiyo_box.find_all("td")

# 変数化
kcal = eiyoso[0].string
p = eiyoso[1].string
f = eiyoso[2].string
c = eiyoso[3].string

print("サバの塩焼定食\n" + "kcal " + kcal)
print("P " + p)
print("F " + f)
print("C " + c)
```

こう

```shell-session:
$ python3 getYayoi.py
サバの塩焼定食
kcal 768
P 36.3
F 37.6
C 70.5
```
Docker用とVirtual Box用のWindowsの選択起動画面を表示させる方法


VirtualBox 6.0ではHyper-Vとの共存が可能になったとのことでしたが、私の環境で試してみたらVirtualBox内のDebianが立ち上がらず、うまくいきませんでした。[こちら](https://docs.oracle.com/cd/E97728_01/F12470/html/hyperv-integ.html)のOracleのドキュメントではExperimental featureとされており、まだ問題があるようなので、しばらく再起動して切り替える必要がありそうです。

Hyper-Vを利用するDocker Desktop for Windowsと、Hyper-Vと共存できないVirtual Boxをどちらも同一のマシンで利用したい場合、ブートオプション画面を表示させ、Hyper-VがOnまたはOffのどちらの状態でWindowsをブートするか選択可能にする方法がネットにあったのでメモしておきます。

管理者権限でコマンドプロンプトを起動し、次のコマンドで現在のブートローダー(current)をコピーして新しいエントリーを作成します。表示名は何でもよいですが、この例ではNo Hypuer-Vにしています。

```console
> bcdedit /copy {current} /d "No Hyper-V"
エントリ {193f34a8-3ddb-35d2-3f9c-20349842c9fc} は正常に作成されました。
```

単に``bcdedit``を実行すると、currentの設定に加え上記のエントリとその内容が確認できます。次の、このエントリの``hypuervisorlaunchtype``設定をオフにします。

```console
> bcdedit /set {193f34a8-3ddb-35d2-3f9c-20349842c9fc} hypervisorlaunchtype off
この操作を正しく終了しました。
```

これエントリが作成できました。シフトキーを押しながら再起動すると、起動時に作成した"No Hyper-V"が選択できるようになります。

上記の例ではデフォルトでHyper-Vを有効、オプションで無効という設定を想定していますが、
デフォルトで無効、オプションで有効にする場合は、currentの``hypervisorlaunchtype``が``off``になっている状態でエントリを上記の方法でコピーし、コピーされたエントリの``hypervisorlaunchtype``を``auto``に設定します。

**参考**
* [Yashints | Switching between VirtualBox and Hyper V](https://yashints.dev/blog/2018/04/13/switching-between-virtualbox-and-hyper-v)
* [Hyper-V をオン/オフする方法 - Qiita](https://qiita.com/masoo/items/b73dadb0e99f9be528fe)
* [Windowsのbcdeditでブートメニューの項目を追加する：Tech TIPS - ＠IT](https://www.atmarkit.co.jp/ait/articles/0905/15/news111.html)
* [Windowsのbcdeditでブートメニューの表示順序やデフォルトを変更する：Tech TIPS - ＠IT](https://www.atmarkit.co.jp/ait/articles/0905/08/news096.html)
QNAP NAS TS-251Bのメモリを増設したメモ

#１．メモリ増設の経緯とか
Container Stationを導入したところ、メモリ使用量が増加したこと。
またWEBアプリの動作がモッサリしてきたこと。

その他、代替メモリの情報として
お約束ですが代替品手配・交換は自己責任で
【システム性能と安定性を維持するため、同じタイプと容量のQNAPモジュールだけを使用してください。QNAPメモリモジュールは認定リセラーで購入できます。】

# ２．使用機器
QNAP:TS-251B-2G

# ３．仕様確認
●公式Accessories Store
Price: US$110.00
Model:RAM-4GDR3LA0-SO-1866
Description:  4GB DDR3L-1866 204Pin SODIMM RAM Module

●その他WEB上
QNAP(キューナップ)専用増設メモリ DDR3L-SO1866-8GB-KIT 4GB 2枚パック センチュリーマイクロ製
¥18,633　高い。。。パッケージ写真ではCL13
DDR3L-SO1866　4GBを中古で探すも結構高い。

# ４．代品検討
Crucial 4GB CT51264BF186DJ 
仕様: DDR3 PC3-14900 • CL=13 • Unbuffered • NON-ECC • DDR3-1866 • 1.35V • 
国内在庫なし

# ５．注文
amazon.comに在庫あり。
Crucial 4GB Single DDR3/DDR3L 1866 MT/s (PC3-14900) Unbuffered SODIMM 204-Pin Memory - CT51264BF186DJ
$19.95 ×2枚購入

■購入費用
Item(s) Subtotal:$39.90
Shipping & Handling:$5.15
Total before tax:$45.05
Estimated tax to be collected:$0.00
Grand Total:$45.05

■到着までの日数
7/20に注文
8/5到着予定が7/31到着

# ５．取付け・動作確認
一旦シャットダウン
取り外し・取付け手順はマニュアル「TS-251Bユーザーガイド」の「メモリモジュールの交換」参照。

再起動して認識状態確認
![メモリ使用量.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466152/a9c5ed68-b0c3-722e-2c97-363bb24b21d5.jpeg)
WEBアプリの動作がクイックになりました。
flutterでfirebase_authを追加したらRunning Xcode build...から進まない現象の対処法

pubspec.yamlに

```
dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  rxdart: ^0.22.1+1
  firebase_auth: ^0.14.0+
```
と「firebase_auth」を追記すると、永遠に「Running Xcode build...」で終わらない。
<img width="473" alt="スクリーンショット 2019-08-11 12.00.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47132/4de1ec00-5b06-3743-8f21-e523506def82.png">

# 対処法
[Firebase flutter-setup](https://firebase.google.com/docs/flutter/setup)を確認すると、ios/RunnerにGoogleService-Info.plistを入れろと書いてあるけど、直接フォルダに入れても同じ現象になるので注意。
xcode上からGoogleService-Info.plistを追加してあげないと認識できないみたいで、この手順を実施すれば正常にビルドできるようになる。
<img width="1140" alt="スクリーンショット 2019-08-11 12.10.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47132/363dff6f-7632-2aaa-d822-5ef7e0a691f0.png">

# おわりに
わかるかこんなの！2時間ハマったわ。だからネイティブは(ry
JavaScript 正規表現(RegExp:Regular Expression)メモ


# JavaScriptで利用できる主な正規表現パターン

|パターン|マッチする文字列|
|:----:|:----:|
|ABC|「ABC」という文字列|
|[ABC]|A,B,Cのいずれか1文字|
|[^ABC]|A,B,C以外のいずれか1文字|
|[A-Z]|A〜Zの間の1文字|
|A&#124;B&#124;C|A,B,Cのいずれか|
|X*|0文字以上のX|
|X?|0、または1文字のX|
|X+|1文字以上のX|
|X{n}|Xとn回一致|
|X{n,}|Xとn回以上一致|
|X{m,n}|Xとm〜n回一致|
|^|行の先頭に一致|
|$|行の末尾に一致|
|.|任意の1文字に一致|
|\w|大文字/小文字の英字、数字、アンダースコアに一致(=[A-Za-z0-9_])|
|\W|文字以外に一致(=[^\w])|
|\d|数字に一致（=[0-9]）|
|\D|数字以外に一致(=[^0-9])|
|\n|改行（ラインフィード）に一致|
|\r|復帰（キャリッジリターン）に一致|
|\t|タブ文字に一致|
|\s|空白文字に一致(=[\n\r\t\v\f])|
|\S|空白以外に一致(=[^\s])|
|\〜|「〜」で表される文字|

# オブジェクトの生成

```javascript
var 変数名 = new RegExp('正規表現', 'オプション'); //コンストラクター

var 変数名 = /正規表現/オプション; // リテラル
```

#### 正規表現のオプション
|オプション|概要|
|:-:|:-:|
|g|文字列全体にマッチするか（無指定の場合、1度マッチした時点で処理を終了）|
|i|大文字/小文字を区別するか|
|m|複数行に対応するか(改行コードを行頭/行末と認識)|
|u|Unicode対応(ES2015)|

#### エスケープ
コンストラクター構文では**「 \ 」**、リテラル構文では**「 / 」**をエスケープする必要がある。

# 正規表現による検索・検証・置換・分割
## String.match
**String.matchメソッド**はマッチした文字列を配列として取得する。
gオプションを無効にした場合、**「最初にマッチした文字列全体」**と**「サブマッチ文字列」**を取得する。
（**サブマッチ文字列**：正規表現パターンの中で丸カッコで示された部分(サブマッチパターン)に合致した部分文字列。マッチしている部分がない場合はundefined、複数マッチしている場合には最後にマッチしたものを保持する。）

```javascript
str.match(pattern)
  // str:検索対象の文字列
  // pattern:正規表現
```
## RegExp.exec
**RegExp.execメソッド**はgオプションの有無にかかわらず、1度の実行で1つの実行結果しか返さず、マッチした文字列全体とサブマッチ文字列を配列として返す。
**execメソッド(RegExpオブジェクト)**は**「最後にマッチした文字位置を記憶する」**ため、次にexecメソッドを実行する場合、RegExpオブジェクトは**「前回のマッチ位置から検索を再開」**する。検索結果がない場合はnullを返す。

```javascript
regexp.exec(str)
  // regexp:正規表現
  // str:検索対象の文字列

// 全てのマッチング結果を得る場合
while ((result = regexp.exec(str)) !== null){
  // 繰り返し処理
}
```
## RegExp.test
**RegExp.testメソッド**を使うことで、単に正規表現にマッチしているかどうかを真偽値で返すことができる。

```javascript
regexp.test(str)
  // regexp:正規表現
  // str:検索対象の文字列
```
## String.search
**String.searchメソッド**は、指定した正規表現で最初にマッチした文字位置を返す。マッチした文字列が存在しない場合は戻り値として-1を返す。

```javascript
str.search(pattern)
  // str:検索対象の文字列
  // pattern:正規表現
```
## String.replace
**String.replaceメソッド**は、正規表現でマッチした文字列を置換することができる。
引数のrepには「\$1...$9」の特殊変数を埋め込むことができる。
特殊変数はサブマッチ文字列を保存するための変数。

```javascript
str.replace(pattern, rep)
  // str:置き換え対象の文字列
  // pattern:正規表現
  // rep:置き換え後の文字列
```
## String.split
**String.splitメソッド**は、正規表現で文字列を分割することができる。

```javascript
str.split(sep[, limit])
  // str:分割対象の文字列
  // sep:区切り文字（正規表現）
  // limit:分割回数の上限
```

# 出典
[改訂新版]JavaScript本格入門　山田祥寛著
Rubyで競プロ、ちょっと高速化テク(ABC137D)

abc137d, abc128eのネタバレを含むので、
ネタバレ無しで解きたい方は説いてから御覧ください。

### 問題
https://atcoder.jp/contests/abc137/tasks/abc137_d  

### 解説
https://img.atcoder.jp/abc137/editorial.pdf  

### 手順
<details><summary>解答フロー</summary><div>

[報酬がもらえるまでの日付, 報酬]を日付で昇順ソートして、  
`今日からM日後` までにもらえる報酬を最大化するための仕事の割り振りを、
今日から考えるのではなくM-1日後の仕事の予定から埋めていくイメージになります。  

M-1日後にやって、1日後(今日からM日後)までに報酬がもらえる仕事の内最大の報酬の仕事を取る、
M-2日後にやって、2日後(今日からM日後)までに報酬がもらえる仕事の内最大の報酬の仕事を取る、
...
今日やってM日後までに報酬がもらえる仕事の内最大の報酬の仕事を取る。

という形で報酬の最大化ができます。(自明)  
1日後に報酬がもらえる仕事の報酬を最大Heap(親ノードの方が必ずでかい)にぶっこんで、1個pop(最大値を取り出す)、
2日後に報酬がもらえる仕事の報酬を最大Heapに全部ぶっこんで、1個pop
...
という形で時間内に答えることが出来るはずです。  

こういうデータ構造はABCのDぐらいだとちょくちょく求められるので予め作っておいた方が無難です。  
https://github.com/k-karen/ruby-samples/blob/master/heap/pop_heap.rb  
私の最大Heapを置いておきます、よろしければご利用ください。

</div></details>

### 高速化テク  
ということで今回は[日付, 報酬]の配列を日付でsortしたいという場面が出てくると思います。  
普通にやると


```ruby
n, m = gets.split.map(&:to_i)
datas1 = []
n.times do
  datas1 << gets.split.map(&:to_i)
end
datas1.sort_by!(&:first)
```

と書くと思いますが、 `sort_by!(&:first)`は(後述の方法より)早くないです。
今回は入力が全部正の値で、その上限が10^5程度とわかっていますので、
これを利用して以下のように書くことができます

```ruby
# (10**5).bit_length #=> 17
# 17ビットずらせば、2つの値を独立に保存できる
n, m = gets.split.map(&:to_i)
datas2 = []
n.times do
  tmp = gets.split.map(&:to_i)
  datas2 << (tmp[0] << 17) + tmp[1]
end
datas2.sort!
```

これだと気持ち早くなります。

値を取り出すときは予めビットマスクを用意しておいて、それとandを取れば良いです。

```ruby
mask = (1 << 17) - 1 
datas.each do |day_salary|
  day = day_salary >> 17
  salary = day_salary & mask
end
```

### どんぐらい早くなるか
before( max 817ms )
https://atcoder.jp/contests/abc137/submissions/6816390
after ( max 775ms )
https://atcoder.jp/contests/abc137/submissions/6840374  
今回はあまり効果がありませんが、
多重キーソートも値の順番を正しく配置すればいい感じに行えます(ABC128E)
降順と昇順が入り交じる場合は、入力の上限から引いた値を入れるなどの工夫が必要になります。



俗に言うイベントソートで大活躍する手法です。
そもそもそんな小手先の高速化を行うなら、
RubyじゃなくてC++でかけという話、ごもっともなので勘弁してください。

最後に、同じような手法で出来る問題置いておきます。
https://atcoder.jp/contests/abc128/tasks/abc128_e
Rubyハッシュからの取り出し

ハッシュからの取り出しが頭から抜けていたので復習もかねて。
ターミナルから以下のデータを取り出す。

George
Alice
Taro

問題

```rb

user_data = [
  {
    user: {
        profile: {
            name: 'George'
        }
    }
  },
  {
    user: {
        profile: {
          name: 'Alice'
        }
    }
  },
  {
    user: {
        profile: {
            name: 'Taro'
        }
    }
  }
]

```

答え

```rb
user_data.each do |u|
  puts u[:user][:profile][:name]
end
```
あるいは

```rb
user_data.each{ |u| puts u.dig(:user, :profile, :name) }
```
配列の範囲指定をうっかり間違えたために本当にあった怖い話

# 要点
 - Rubyの配列の要素取り出しは `ary[p..q]` と `ary[p...q]` という表記があって、Python の `ary[p:q]` に相当するのは後者。
 - オーディオサンプリング周波数 44100 を 4 倍して 1 足すと素数になる (←知ってました?)。
 - FFT の一番広く使われている Cooley-Tukey のアルゴリズムはデータを因数分解した数に分けて細切れにしていく。

以上で何がいいたいかわかった方はそれで十分です。気をつけましょう…

# 本当にあった怖くて恥ずかしい話

Python の numpy で 4 s のオーディオ信号を FFT するプログラムがありました。

ぼくは Python が嫌いなので、それを mrkn 氏の素晴らしい Pycall (https://github.com/mrkn/pycall.rb) を使って Ruby に移植しました。その際、Python で 4 s 切り出す `data[ptr:ptr + 44100 * 4]` という感じの部分を、**うっかり`data[ptr..(ptr + 44100 * 4)]` と書いてしまった** のです。もちろん正解は `..` ではなく `...` です。

その結果 **謎のフリーズ**。いや実際は単に計算に時間がかかっていただけなんですが、10 s 以上も固まれば、そりゃ `^C` 押しますって。そして何は原因なんだろうpycallかな、などとあらぬ疑いを頓珍漢な方向に向けたりして **リアルに3-4時間くらい時間を無駄にしました**。(恥ずかしい。)

# 衝撃の再現コード

巷では Python の方が人気と聞くので Python のみで動くように書きました。実行すれば驚きを体験できます。

```python
#!/usr/bin/python3
import numpy as np
fs = 44100
duration = 4
data = np.random.randn(fs * 10)           # dummy data
print("test 1")
y = np.fft.fft(data[0:fs * duration])
print("test 2")
y = np.fft.fft(data[0:fs * duration + 1])
```

本当はいろいろ Ruby で書きたいんだけど numpy とか keras とかがないから必要悪と割り切って Python を使っている人は pycall.rb (やそれを使った numpy.rb) を使いましょう！上記のコードならこんな↓感じにほぼベタ移植できます。すごい > pycall

```ruby
#!/usr/bin/ruby
require "numpy"                           # gem install numpy
fs = 44100
duration = 4
data = Numpy.random.randn(fs * 10)        # dummy data
puts "test 1"
y = Numpy.fft.fft(data[0...fs * duration])
puts "test 2"
y = Numpy.fft.fft(data[0..fs * duration])
```

# おわりに

 - Ruby は文法がきれいで書きやすくて好きなんですが、まさかこういうハマり方をするとは思ってもいませんでした。自分が悪いんですけど。
 - $44100\times4+1$ という大きめの覚えやすい素数が手に入ったのは収穫。ちなみに $44100\times4-1 = 419\times 421$ も
ふたつの素数の積なので注意。
Debian10(Buster)でvisudoがないと言われたときの対処

Debian Busterでユーザーでログインしてからsuに入ったとき、visudoが使えないことがあったのでメモ。  

## 解決法

問題は単純で、suにハイフンを追加することで解決する。
suはオプションにハイフンをつけなければ環境変数がsuに入る前のユーザーのものになってしまう。
それが今回の問題を招いてしまった。  

``` shell:例  
su -   # 環境変数をrootのものに変更
visudo
```    

## 参考文献  

[su, su -, su -- の違い](https://qiita.com/takewaka/items/9f728bb05b4cf7a392e9)　　
[I can't seem to run visudo on debian buster](https://www.reddit.com/r/debian/comments/cfgpj8/i_cant_seem_to_run_visudo_on_debian_buster/)
サーバレスでRSSを取得しDynamoDBに登録する30行

とあるサイトの情報をRSSで取得し、DynamoDBに突っ込むだけの処理。最初、ライブラリとかをアップロードしないとできないかなと思ったが、標準ライブラリだけで大丈夫だった。CloudWatch Eventsから起動して使う。

```py
import urllib.request
import xml.etree.ElementTree as ET

import boto3
import json
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('xxxxxxxx')

def lambda_handler(event, context):
    cnt = 0
    url = 'https://note.mu/usop/m/m79fbb598dd82/rss'
    with urllib.request.urlopen(url) as response:
        html = response.read()
        root = ET.fromstring(html)        
        for item in root.iter('item'):
            link = item.find('link').text
            res = table.scan(
                FilterExpression=Attr('url').eq(link)
            )
            if res["Count"] == 0:
                resall = table.scan()
                cnt = resall["Count"]
                table.put_item(Item={"id":cnt+1,"url":link})
    return {
        'count': cnt
    }
```
PowerPointで自動字幕を使ってみる

とある勉強会で、PowerPointの自動字幕を使われてるのを見た。話しているそばからテキスト化されて、プレゼンでは十分なスピードだと感じた。日本語だと精度はそれなりな部分あるけど、説明会やオンラインミーティングで聞き取りづらいときでも、字幕があれば伝わりやすそう。

実践で試してみたいな・・・と思い、早速使ってみたところ反響が結構あったので、使い方と引っかかったことをちょっとまとめてみた。


#公式の案内

Microsoftの公式サイト内で、[PowerPoint でのリアルタイムの自動キャプションまたは字幕の表示](https://support.office.com/ja-jp/article/powerpoint-%E3%81%A7%E3%81%AE%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E3%81%AE%E8%87%AA%E5%8B%95%E3%82%AD%E3%83%A3%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%BE%E3%81%9F%E3%81%AF%E5%AD%97%E5%B9%95%E3%81%AE%E8%A1%A8%E7%A4%BA-68d20e49-aec3-456a-939d-34a79e8ddd5f)として案内されてる。

日本語は、20190811時点では、プレビューの扱いになってる。

#PowerPointのブラウザ版で試してみる

すんなり、使える。


ファイルを開いて、表示タブの「常に字幕を使用する」で設定する。ただそれだけ。
話し手と字幕の言語で、自動翻訳も設定できる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/9a5f5d07-a993-9168-77d9-59ddb59f9235.png" width=50%>


インターネットにつないだ状態でスライドショーにして、すぐに字幕化が始まる。
1秒もないぐらいでどんどん文字になっていく。素敵。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/18759c8d-ba6e-d398-7055-93b4547f2824.png" width=50%>


#PowerPointのデスクトップ版で試してみる

20190811時点では「PowerPoint バージョン 16.0.11231.20070 以降が必要」とある。
ただ、手元の環境は16.0.11901なんだけど、使えない。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/ac0095d9-2f40-dd7d-33c8-0435e281bd22.png" width=50%>

なんでなんだろな・・・。とある勉強会で見たスライドでは字幕出てたので、何か足りないだけかもしれない。





#PowerPointのiOS版で試してみる

残念ながら、リリースされていない。なので、字幕を使いたい場合、私の環境では現時点でPCでブラウザのみ。


#まとめ

インターネットにつながっていればリアルタイムで翻訳してくれる。もちろん、精度はそれなりな部分あるのでそこは差し引いて考えなきゃいけない。

とはいえ、使える部分は結構あるし、今後精度も上がっていくと思う。一度試してみることをおススメします。
情報処理安全確保支援士 平成21年度秋 午前II 問18

情報処理安全確保支援士の資格試験を受けるにあたり、以下のサイトで非常に捗っています。電車内での空き時間にスマホで勉強できるので、午前IIはここをやっておけばパスできます。午前IIしかないので午前I免除の人はおトクです。
https://www.sc-siken.com/sckakomon.php
いつもありがとうございます:blush:

試験という限られた時間の中ですので、より効率の良い解き方が必要になります。この記事はその補足です。

(2019/11/28追記)
ほとんど同じ問題のより詳しい解説です。とっくの昔に解説されてました。
https://qiita.com/kitoo/items/9d7f8bad76dd37b51e7d

# 問題解説
https://www.sc-siken.com/s/kakomon/21_aki/am2_18.html

# 解説補足
###224 の ２進数ビット列への変換
$255-224 = 31$ であり $2^5 = 32$ ですので、
$31=2^4+2^3+2^2+2^1+2^0$ 

すなわち1バイト（＝8ビット)のうち下位5ビットが0になります。
224 → 1110 0000

よくあるネットマスクは覚えておいた方が速いかもしれませんといったら身も蓋もないですが、ネットワークエンジニアの人は覚えてるんでしょうね。

| ネットマスク | IPアドレス数 | マスク下位 |
|:--|:--|:--|
| 255.255.254.0 | 512 | `..10 0000 0000` |
| 255.255.255.0 | 256 | `..11 0000 0000` |
| 255.255.255.128 | 128 | `..11 1000 0000` |
| 255.255.255.192 | 64 |  `..11 1100 0000` |
| 255.255.255.224 | 32 |  `..11 1110 0000` |
| 255.255.255.240 | 16 |  `..11 1111 0000` |
参考：https://note.cman.jp/network/subnetmask.cgi

###下位8ビット「90」を224でマスクした値
$1110 0000=2^8+2^7+2^6$ ですので、
90から、$2^8=255,2^7=128,2^6=64$ を引くことを考えます。
引けるのは、64 なので、90-64=26 となります。
COLLATE "ja_JP.utf8" asc が動かない

## 問題

もともと `postgres10.9` のイメージを使っていたが

```sql
COLLATE "ja_JP.utf8" asc
```
みたいな検索条件がある時に動かない。

## 解決方法

引っ張ってきたイメージには `en_US.utf8` しかないので、下記の通り変える

### 変更前

```Dockerfile:docker-compose.yml
  pgsql:
    image: postgres10.9
```

### 変更後

```Dockerfile:docker-compose.yml
  pgsql:
    build: ./docker/db
```
```Dockerfile:./docker/db/Dockerfile
FROM postgres:10.9
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
```

## 調べてた時の作業内容

#### localeコマンドを売ったら `ja_jp.utf8` で設定されてない

```bash
root@cf87121a0be7:/# locale
LANG=en_US.utf8
LANGUAGE=
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=
```

#### `local -a` を打ったら `ja_jp.utf8` がない

```
root@8dc095cd908f:/# locale -a
C
C.UTF-8
en_US.utf8
POSIX
```
TCP 接続で syslog サーバにログを送ると、syslog サーバが停止している場合、rsyslogd 本体が停止してしまう

メールシステムなど複数サーバからなるシステムを運用している場合、トラブルシュートを行う時に複数サーバの `/var/log/` を横断検索するのは大変なので、

* 各サーバの `/var/log/` にログは蓄積する
* 同時に、syslog サーバにもログを転送しておく

と設定をするのは、ごく自然な話だと思います。が、今回、その設定で痛い思いをしました。

192.0.2.17 で動作しているメールサーバ（Postfix や Dovecot が稼働）には、以下のように設定が書いてあり、同一サブネット内の syslog サーバ（192.0.2.65）だけでなく、遠隔地の syslog サーバ（198.51.100.65）にもログを転送しています。

```conf:/etc/rsyslog.d/forward-syslog.conf
mail.* @@198.51.100.65
mail.* @@192.0.2.65
```

遠隔地の syslog サーバ（198.51.100.65）が停電により停止していると、192.0.2.17 で動作している rsyslogd は、遠隔地の syslog サーバとの通信を開始しようと SYN パケットを送ったまま、そこで処理が止まってしまいます。

```shell-session
root@mx1:/local/tutimcadmin# netstat -nap | grep syslog
tcp        0      1 192.0.2.17:46698       198.51.100.65:514        SYN_SENT    11353/rsyslogd  
unix  5      [ ]         DGRAM                    1699971854 11353/rsyslogd      /dev/log
unix  5      [ ]         DGRAM                    1699971856 11353/rsyslogd      /var/spool/postfix/dev/log
```

すると、症状としては、`/var/log/syslog` に rsyslogd が再起動したよというログは残るのですが、Postfix や Dovecot などのログは一切 `/var/log/mail.log` に出てこないだけでなく、192.0.2.65 で動作している同一サブネット内の syslog サーバにも全くログが転送されないという状況になります。

```text:/var/log/syslog
Aug 11 10:03:45 mx1 rsyslogd: [origin software="rsyslogd" swVersion="5.8.11" x-pid="11353" x-info="http://www.rsyslog.com"] start
```

Postfix は `/dev/log` に書き込みができない場合、SMTP セッションそのものは受け付けるのですが、その後、応答ができなくなってしまうらしく、`/proc/net/nf_conntrack` を調べてみると、ESTABLISH されているのに UNREPLIED なセッションが大量に存在しているという状態になります。

```shell-session
root@mx1:/local/tutimcadmin# cat /proc/net/nf_conntrack|grep ESTABLISHED|grep UNREPLIED|wc -l
1065
root@mx1:/local/tutimcadmin# cat /proc/net/nf_conntrack|grep ESTABLISHED|grep UNREPLIED|tail -1
ipv4     2 tcp      6 303348 ESTABLISHED src=192.0.2.17 dst=203.0.113.42 sport=25 dport=53413 [UNREPLIED] src=203.0.113.42 dst=192.0.2.17 sport=53413 dport=25 mark=0 zone=0 use=2
```

syslog に記録が出てこないため、トラブルシュート初期の段階で rsyslogd の動作は疑ったのですが、

* rsyslogd のプロセスは存在している。
* `/var/log/syslog` に rsyslogd が起動したというメッセージは出ている。
* `rsyslogd -N 1` と `/etc/rsyslog.conf` の文法チェックを行なってもエラーも警告も出ない。

という状況で、ネットワークやハードウェアなどより低レイヤーが原因となっている可能性を疑ったため、rsyslogd が原因であると辿り着くのに時間を要しました。

というわけで、 rsyslog-5.8.x を使って TCP 接続でログを送信する設定を行う場合は、十分な検証が必要です。
少なくとも rsyslog-8.4 ならば、TCP 接続および RELP 接続ともにタイムアウトして、rsyslogd 本体の機能は維持されるようなので、素直に rsyslog を更新したほうが良さそうです。

また、検証は相当に厄介そうです。まず、同一サブネット内の存在しないサーバを指定しても、上記の症状は再現できませんでした（停電中のサーバを指定すれば再現できる）。また、同僚の記憶によれば、2018年の停電時も同じ設定だったはずということなので、2018年には発生しなかったトラブルが何故2019年には発生したのか？の理由も不明のままです。
Bulma+Vue.js モバイル対応用 Navbarの動作

下記の記事を参考に実装したが、
バーガーメニューが開いてNavメニューをクリックしてもバーガーメニューが閉じてくれない。

「BulmaのハンバーガーメニューをVue.jsで実装する」
https://qiita.com/seki19/items/649b317c10e84fb36e06

ポイントは、下記にメニューなどをクリックした場合を追加

```  <div id="navbarBasicExample" class="navbar-menu" v-bind:class="{'is-active': isOpen}">　　```

@click="isOpen = !isOpen"を追加する。

```  <div id="navbarBasicExample" class="navbar-menu"　@click="isOpen = !isOpen" v-bind:class="{'is-active': isOpen}">　　```

となる。
GatsbyとNetlifyで簡単にブログを作成


# 概要
[Gatsbyのスターター](https://www.gatsbyjs.org/starters/?v=2)と、[Netlify](https://www.netlify.com/)を使用して誰でも5分で爆速ブログを作成する方法を紹介します。

記事内では[こちら](https://elastic-montalcini-5361d7.netlify.com/)のブログをデプロイまで行います。

# Gatsbyとは？
Gatsbyに関してはこの方の記事でとても良く説明されています。

- [Reactベース静的サイトジェネレータGatsbyの真の力をお見せします - Qiita](https://qiita.com/uehaj/items/1b7f0a86596353587466)

# Gatsbyのインストール

Gatsbyがインストールされていない場合は以下のコマンドでインストールしましょう。

```
$ npm install -g gatsby-cli
```

# ブログの作成
以下のコマンドでブログを作成します。

- `my-blog`の部分でブログの名前を指定します。
- `https://github.com/gatsbyjs/gatsby-starter-blog`の箇所は使用するスターターを指定します。

[こちら](https://www.gatsbyjs.org/starters/?v=2)から好きなデザインを選ぶ事が可能です。

```
$ gatsby new my-blog https://github.com/gatsbyjs/gatsby-starter-blog
```

# ローカルで確認
作成したブログのディレクトリに移動し、ローカルでブログを確認しましょう。

以下のコマンドを実行すると、`http://localhost:8000/`でブログが起動している事が確認できます。

```
$ cd my-blog
$ gatsby develop
```

# 新しい記事の追加
`content/blog`に新しいマークダウンファイル(`.md`)を追加してみましょう。
すると、自動でブログに記事が更新されている事が確認できます。

```md
---
title: テスト記事
---

今日はいい天気だな。
```

# ブログをGitHubにプッシュする。

[Netlify](https://www.netlify.com/)を使用したデプロイ方法ではデプロイしたいサイトがGitHub/GitLab/Bitbucketで管理されている必要があります。
本記事ではGitHubを使用します。

```
git init
git add .
git commit -m "Initial commit"
```

```
git remote add origin https://github.com/yourname/your-blog-name.git
git push -u origin master
```
# ブログをデプロイする

[Netlify](https://www.netlify.com/)のアカウントがない場合は作成しましょう。
アカウント作成後、以下の`New site from Git`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258219/c1b5411c-a1f2-9d1e-4d2f-e2debb6cdba4.png)

今回はGitHubからのデプロイなので、GitHubを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258219/aac29504-2404-4ceb-9d73-e78e6acdf7d6.png)

デプロイするレポジトリで作成したブログのレポジトリを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258219/67490813-4e31-731e-74e3-df9c4ff784b4.png)

次の画面で`Deploy site`をクリックする事でデプロイが始まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258219/99219f80-c631-2cd3-6f63-ff2b2cffb7fe.png)

デプロイができたら、サイトを確認してみましょう。
ここでは `https://elastic-montalcini-5361d7.netlify.com`がサイトのURLになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258219/6af38594-bb62-62ad-50bd-15b6483ac31e.png)

# URLの変更
URLが気にくわない場合は `Site settings` をクリックし、`Change Site name`で`netlify.com`以前のURLを変更する事が出来ます。
また、カスタムドメインを使用することも出来ます。

# デプロイ後のブログの更新
Neflifyではmasterブランンチにコミットやマージがあると自動的にデプロイが走り、ブログが更新されます。
ですので、記事を追加したり、デザインを変更した後に、GitHubでmasterブランチにその変更をプッシュするだけでサイトの更新が可能です。

# 参考

- [Start a Blog in 2019 with Gatsby.js and Netlify](https://daveceddia.com/start-blog-gatsby-netlify/)
Pythonでzipファイル解凍後の文字化け解消

「ファイル名に日本語つかわないでよー:sob:」

音声ファイルを取引先が送ってきました。zipで圧縮されていたので解凍しようとしたらめちゃんこ困ったことになりました。ファイル名がことごとく文字化けしてるんです。ファイル名がわからないと何の音源がわからない。

ファイル名に日本語を使わなければこんなことにはならないと思うんです。Qiita読者諸兄なら、取引先とのやり取りには英数字のファイル名を使ってると思います。しかし世間にはそういう認識ってまだまだ足りてないのかなと。

「文字化けしてるんで圧縮しなおしてください」って頼むとまた時間がかかるし、私達には頼れる存在、**Python**がついています！

Pythonをつかって正しいファイル名で解凍してみます（Python3）

```python3

import zipfile

SRC = '解凍したいzipファイル'
DST = '解凍したファイルを置きたい場所'

with zipfile.ZipFile(SRC) as z:
    for info in z.infolist():
        info.filename = info.filename.encode('cp437').decode('utf-8')
        z.extract(info, path=DST)
```

私の今回のケースの場合、文字コード`cp437`を使えば正しいファイル名に変換できました。ここは先方の使っている環境によって変わってくるかもしれません

以上、ちょっとしたコツですが、お役に立てば幸いです。くれぐれも、やり取りは英数字のファイル名で
Pragmatic Terraform on AWSでお勉強〜其の一

技術書展6で頒布されたPragmatic Terraform on AWSの電子版を購入しましたので、手を動かながらのレビューです。
本当は紙で欲しかったのですが開場1時間程度で完売だったとのことですので電子版です。
紙だけの販売だったらTerraformの理解がまた遅れてました。。著者様に心から感謝いたします。

https://nekopunch.hatenablog.com/entry/2019/02/18/225657
https://booth.pm/ja/items/1318735

##第1章〜3章、入門編
余計なことが書かれていないので素直に写経。わかんないとこはググりながら進めます。
クレデンシャル？って一瞬なりましたがIAMのアレ（語彙）か、と解決までの時間が短かったのはちょっと嬉しかった。
確かこの辺りは下記記事を参考に設定した気がします、IAMの理解も深まるしセキュアになるしで一読を推奨。

https://qiita.com/tmknom/items/303db2d1d928db720888

##いきなりハマる
が、やはりそう上手くはいかないw
結論はプライベートAWS環境のリソース整理したときにデフォルトのVPCも削除してしまったから、なのですが結構悩みました。

```
$terraform apply

aws_instance.example: Creating...

Error: Error launching source instance: VPCIdNotSpecified: No default VPC for this user
	status code: 400, request id:
```
 
デフォのVPCを作成して再実行し、無事解決！
Dockerの時もそうだったのですが手動でポチポチやってたレガシー勢が進化した感じはとても嬉しいですね。

ちなみに著者様の記事でハマりどころポイントを解説していたのですが、terraform initでもエラーがでらず。
かつ、AWSプロバイダのバージョンは1.6ではなく2.11なのですが動きました。
というか手動でmkdirしてバイナリファイル置いてもinitしたら2.11になるのですが、
この辺りの切り替え手段とか、そもそもAWSプロバイダがなんなのかわからんw！

読み進めて理解が深まったらいいなあ〜。

https://nekopunch.hatenablog.com/entry/2019/04/18/094914
Slackかかってこいや！

Slack力（すらっくりょく）が全エンジニア一低い気がしましたので調べたり手を動かしたり。
大変素晴らしいツールであることを実感しました。最高。

##チャンネルの作成
+を押す。つくる。

・パブリック
 
ワークスペースのメンバーであれば誰でも閲覧・参加することができるとのこと。
チャンネル名の先頭に＃がつく。

・プライベート
 
招待されて閲覧・参加が可能。
チャンネル名の先頭に鍵マークがつく。

##チャンネル名の変更
素直に設定からやればOK。名前が長すぎるとおいおい勘弁してくれよ〜って感じで優しく指摘されます。


##メンション
@here
特定のチャンネルで、オンラインのメンバ全員にメンションを飛ばす。

@channel
特定のチャンネルに登録されているメンバ全員にメンションを飛ばす。
オンライン/オフラインは問わない。
今から本番環境のfooへbar作業を開始します！とか作業周知するときはこっち、そうでなければhereとか。

##チャンネルの削除
ワークスペースのオーナーと管理者のみ可能。ローカルアカウントで迂闊に作るとあまりよくない未来が見えますね。

##検索フィルタ
command + k　：検索フィルタ表示。GUIの別の会話へ移動をクリックしても同様の結果が得られる。
というかカーソル乗せたらショートカットはコマンドkだよ！ばりに表示される。UXすごい。

「okome_chan」キーワードで検索して出力されたユーザ名を選択するとダイレクトメッセージを送れる。
接頭辞にfrom:が付いている結果を選択するとチャンネルを横断して検索したユーザのメッセージやファイル、チャンネルが確認できる。

##ユーザーグループ
チャンネルと勘違いしてた。作成後にユーザを登録してメンション飛ばすと登録したユーザのみにメッセージがいく。
あとユーザーグループの削除はできないっぽいので、間違って作成した場合は編集して別の用途で使う。。って本当かな？w
公式には書いてなかったのでそうかも、おいおい。


##用語
ワークスペース：このスペースの中にチャンネルを作る。部署とかプロジェクトで分けてるのが一般的。。かは知らないw
 
メンション：特定の相手にメッセージをプッシュ通知する。メンションを飛ばす、って言うらしい
 
アーカイブ：ワークスペース画面のアクティブなチャンネルリストから削除される。メッセージの投稿はできないが閲覧は可能。復元可能。

ショートカットをまだ調べてないのですが、それはおいおい。
下層にあるindexファイルからタイトルを抜き出してリスト化する関数


# はじめに

深夜テンションに身を任せた結果謎のプログラムを錬成してしまったのでアップ。
テストサイトを一々探す手間は省けるかもね。


# コード

```php:test.php

function makelinklist(){

// 現在いるディレクトリのパスを取得
$serverroot = (empty($_SERVER["HTTPS"]) ? "http://" : "https://") . $_SERVER["HTTP_HOST"];
$fileroot = dirname(__FILE__);

	// 下層ディレクトリ名をまとめておくリストを宣言
	$dirset = null;

	// 下層ディレクトリを取得する
	if ( $dirs1 = opendir($fileroot) ){
		while ( ($file = readdir($dirs1)) !== false ){
			// ディレクトリ以外のものを排除している
			if( $file != '.' && $file != '..' && $file != '.htaccess' && $file != 'index.php' && $file != 'index.html' ){
				$dirset[] = $file;
			}
		}
	    closedir($dirs1);
	}

	// リンクのリストをつくる
	foreach($dirset as $va){

		echo '<p class="names">'.$va.'</p>';
		echo '<ul>';


		// 取得した下層ディレクトリのリストを利用して、すべてのindexファイルのパスを取得
		$index_pass = glob($fileroot.'/'.$va.'/index.*');

		// indexが存在するディレクトリのみ、さらにindexファイルのタイトルを取得する処理を実行
		if(!empty($index_pass)){
			if ($dirs2 = fopen($fileroot.'/'.$va.'/'.basename($index_pass[0]), 'r')){

				// 前もってaリンクに使うURLをとってくる
				$curpass = $serverroot.'/'.$va.'/'.basename($index_pass[0]);

				// タイトルタグを検索。範囲は～</head>まで
				while (!feof($dirs2)) {
					$ch = null;
					$line = fgets($dirs2);
					// タイトルタグが見つかったなら、そのタイトルを本文としてリンクを作成
					if (preg_match("/<title>(.*?)<\/title>/i", $line, $matches)) {
						echo '<li><a href="'. $curpass . '">' . $matches[1] . '</a></li>';
						$ch = 'a';
						break;
					}
					// タイトルタグが見つからなかった場合、URLの末尾を本文にしてリンクを生成
					if (preg_match("/<\/head>/i", $line)) {
						echo '<li><a href="'. $curpass . '">' . basename($index_pass[0]) . '</a></li>';
						$ch = 'a';
						break;
					}
				}
				// そもそも<head>～</head>自体がindex内に存在しなかった場合、URLの末尾を本文にしてリンクを生成。<head>～</head>が存在していた場合は上記のbreakを通っている＝変数$chの中身がaになっているはずなので、この判定を通過することはない
				if($ch === null){
					echo '<li><a href="'. $curpass . '">' . basename($index_pass[0]) . '</a></li>';
				}
				$ch = null;
				fclose($dirs2);
			}
		}
		// indexが存在しない場合、すべてのファイルに対して、URLの末尾を本文にしてリンクを生成
		else{
			$elsegroup = glob($fileroot.'/'.$va.'/*.*');
			foreach($elsegroup as $va2){
				echo '<li><a href="'. $serverroot.'/'.$va.'/'.basename($va2) . '">' . basename($va2) . '</a></li>';
			}
		}
		echo '</ul>';
	}

}

```
github○○を捨てる

githubにpushしてみたい！のでやってみました。
端末はmac、以下のQiita記事を参考にさせていただきつつ手を動かしています。
大感謝〜！
あとわかばちゃんと学ぶGitのマンガも読みました。
結構良書ですw

https://qiita.com/nutsinshell/items/96cb83aecf9d09a7a8bc:embed:cite

https://qiita.com/nnahito/items/565f8755e70c51532459:embed:cite

##やってみる
githubアカウントを作成し、リモートリポジトリを作成。

gitは以前にhomebrewでインストールしていたようです。
さっとググっておさらい。バージョンが古そうですが、今回はこれで。

```
# git --version

git version 2.20.1 (Apple Git-117)
```

homeディレクトリにgithub/githubtestディレクトリを作成し、git init。
git initでローカルリポジトリが作成されるとのこと。

ローカルリポジトリ=管理するディレクトリやファイルを置く領域。ディレクトリ。

確かに隠しディレクトリで.initが作成されました。内容はよくわからんのでそっとしておきます。

```
# ls -lha

.
..
.git
```

適当にテキストファイルを作成し、ローカルリポジトリに配置。

```
# vi hellogit

hello my git!github!!
```

git addで変更点をインデックスに追加。
インデックス=変更点をローカルリポジトリに保存する前に登録する場所？
ここにローカルリポジトリ（変更前）との差分を保存する。。のかw？時間経過で具体化できると信じよう。

```
# git add hellogit
```

インデックスに変更点を追加したらコミットする。
コミット=ローカルリポジトリへの変更点の登録。上書き？
で、そのバージョン管理をしているからいついつ変更したファイルを何時でも使用できるのがgit。。のように読み取れますがどうなのでしょうねw
-mはmsgの略とのことです。

```
# git commit -m "はじめてのgithub!"
>
```

改行されて>が出力されましたが、たぶんこれは意図せぬ何かの気がしますw
git commitでググるとgit statusなるコマンドがヒットしました。見てみる。

```
# git status

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   hellogit
```

まだコミットしてませんよ〜できてませんよ〜かな？
適当に手を動かしたら'文字列'で成功しました。

```
# git commit -m 'はじめてのgithub!'
```

これでインデックスの内容がローカルリポジトリへ登録されました。なんか嬉しい。

リモートリポジトリを作成した時に生成されたgithubのURLをインデックスへ登録。
先ほどのインデックスの理解が少し違う気がするけど進める。

```
# git remote add origin URL
```

インデックスに登録したよ！みたいなメッセージはないんですね。
続いていよいよpush。

```
# git push origin master

Username for 'https://github.com':  #githubのUsernameを入力
Password for 'https://Username@github.com':  #Usernameに対するPasswordを入力
```

一瞬ん？となりましたがユーザ名とパスを入力し無事pushできた。。ように見えますのでw、ブラウザで確認。
pushできてる！やったぜ！

ちなみにorigin masterはローカルのmasterブランチを git にpushする、を意味するらしい。
我が地元の雄、Backlogの記事がとてもわかりやすかったです。

https://backlog.com/ja/git-tutorial/stepup/stepup1_1.html:embed:cite

編集してみる。
viで適当に行を追加、インデックスにaddしてgit statusで確認。
commit -mしてpushしてブラウザで確認して完了！手を動かすと理解も早いですね。
コンソール開きっぱで作業したのですが、ユーザ名とパスは聞かれませんでした。
1度pushしたからかな？
ここまでで基本の基本は一旦完了。

##ブランチ
ブランチ。。。。？？？
とりあえずQiita記事にありがたく倣ってみます。

```
git branch testbranch
git branch

* master
  testbranch
```

Railsチュートリアルで見た事あるやつが！！！
うっすらと思い出しました。

ブランチの変更。

```
git checkout testbranch

  master
* testbranch
```

おお。なんか嬉しくなりますねw

ブランチを変更したあとは先の流れ通り。
インデックスにaddしてローカルリポジトリにcommitしてgit push origin testbranch。
ブラウザで確認して完了です。
先人の知恵に感謝感謝であります。

##マージ
testbranchでの変更点をmasterbranchに反映させることをマージと呼ぶそうです。ふむ（わかってない）

git checkout masterでブランチの切り替え後にmergeするようです。
merge後はmasterをpush。

```
git merge testbranch
git push origin master
```

ブラウザでmasterブランチを選択し確認。反映されてました。

##ブランチの削除
お試しブランチ作成時に速攻で間違えたので調べましたw
gitってタブで補完してくれないんですね。プラグインとかあるのかな。

```
git branch --delete ブランチ名
```

本日はここまで。
よく聞くpull、クローン、ローカルのコンソールで作業してる時の切り替え（これはgit）など疑問が残っていますので改めて調べたいと思います。
競プロ1日目

# 今日の教材
今日のところは[この記事](https://qiita.com/drken/items/fd4e5e3630d0f5859067#5-%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-10-%E5%95%8F)にしたがって進めてみました。

# 今日やったこと
## 1. AtCoderでPractice Contestを解く
### 大事だと思ったこと
- 入力と出力の形式に注意を払う。↓Welcome Contestの答えはこのような感じで、入出力のところは競プロ特有かなと思いました。

```python
# -*- coding: utf-8 -*-
# 整数の入力
a = int(input())
# スペース区切りの整数の入力
b, c = map(int, input().split())
# 文字列の入力
s = input()
# 出力
print("{} {}".format(a+b+c, s))
```
## 2. AtCoderで過去問に手をつけてみる
[AtCoder Problems](https://kenkoooo.com/atcoder/#/table//)でABC 136を少しやってみました。
A・B問題は解けました！やはりC問題以降はこれから勉強して対策する必要があるな、という感じでした。

### 大事だと思ったこと

- 紙のメモを用意した方がいい。
- [チートシート](https://qiita.com/_-_-_-_-_/items/34f933adc7be875e61d0)をみて、入力・出力のバリエーションを把握しておいた方がスムーズ。

## ３. 次回やること
- C問題以降の対策方法を考える。
- 入出力の形式はA・B問題を解きながら慣れる。
おれのLinuxは適当すぎる〜コマンドのメモ書き篇

当たり前の事ができるようになりたい！と思い記事化しました。
内容はバリバリ基本レベルです。

Linux標準教科書とLPICの参考書で理解しつつ、手を動かしながら覚えます。
環境はmac。

ファイルを作ってコピーしたりディレクトリも作ったり移動したり消したりします（雑）

##やってみる
まずはvi testlinuxで適当にファイルを作成。デスクトップに作りました。

```
vi testlinux ~/Desktop
```

コピーする前にmkdirでフォルダを作成。
mkdirのオプションはアクセス権を指定する-m、親ディレクトリを同時に作成する-p。
親ディレクトリを同時に作成って要は階層構造にしたいとき、ですね。

```
mkdir -p ~/Desktop/testdir/okome/chan
```

mkdirと同時にフォルダ移動する場合は以下のコマンドで可能。

```
$ mkdir -p ~/Desktop/testdir/okome/chan && cd $_
$ pwd
/Desktop/testdir/okome/chan
```

cpコマンドを適当に叩きましたが結果は同じ。
実行権はコピーできないんですね。たぶん。

```
cp testlinux testlinux2
cp -p testlinux testlinux2
cp -a testlinux testlinux2
```

cpでコピーしてchmodで実行権を与えます。
+で指定するのは結構忘れがち。

```
chmod +x testlinux2
chmod 755 testlinux2
```

ついでにchownとchgrp。どちらも-Rで配下の全ファイルの所有者とグループを変更できます。
いつもchownでまとめてやっています。

```
chown okome:okome testlinux2
```

ディレクトリのコピーには-rが必須とのこと。
ファイルと同じようにやったらエラーが出ました。なんかすまん。

```
cp -r testdir testdir2
```

移動！mvのオプションは2つだけで、同名のファイルやディレクトリが存在するときに
強制上書きするか・上書きする？て聞くかを選択できるようです。
オプション付けなくて同名のファイルやディレクトリが存在するなら
エラーがでる感じだろう。。と思いオプションなしでmvしたら普通に上書きされました。
-iを指定するとちゃんと聞かれたので、業務を意識して-iとセットと覚えた方がよさそうですね。

```
mv -i testlinux testdir
```

rmはよく使うので-iとセットで覚えてます。備忘録。
-i　本当に削除していいと？て聞く
-f　強制削除
-r　再帰的にディレクトリ全体を削除

```
rm -i testlinux2
rm -rf testdir
```

rmdirは空のディレクトリを削除する。結構忘れがち。

```
rmdir testdir
```

gzipでのファイル圧縮はよくわからないまま今日まで来たのでこの機会に。。
何も考えずにgzip。.gz化に成功しますが元のファイルは消えるようです。

```
gzip testlinux2
```

元ファイルを残して圧縮したい場合は-cオプションを利用して標準出力を利用するとのこと。

```
gzip -c testlinux2 > testlinux2.gz
```

##echo
引数で与えた文字列を標準出力に出力する。標準出力。。

```
echo testlinux
```

##export
環境変数を定義・代入する。

```
export X
export X=testlinux
```

##time
スクリプトやプログラムの実行時間を知るときに使用する。
下記記事がスーパーわかりやすかったです。
最近Linux楽しいなーとよく思います。



https://qiita.com/tossh/items/659e5934e52b38183200:embed:cite

##find
本当によく忘れる。ファイル名はわかるけどディレクトリがわからん！ていうよくあるシチュエーションでは以下の通り。

```
$ find ./ -name "filename.txt"
```
##tar
これもよく忘れる。。ファイルのアーカイブ（と圧縮）、解凍（と展開）を行う。
[tarコマンドについて詳しくまとめました 【Linuxコマンド集】
](https://eng-entrance.com/linux-command-tar#i-7)が大変参考になりました:pray:

```
# アーカイブ
# -cでアーカイブを新規作成
tar -cvf [ファイル名.tar] [ディレクトリ]

# 解凍
# -xでアーカイブされたファイルの解凍
tar -xvf [ファイル名.tar]

# 解凍したファイルの展開先を指定
tar -xvf [ファイル名.tar] > $HOME
```

.tgzはtarでアーカイブしたファイルをgzipで圧縮したときにつく拡張子。

```
# gzipで解凍
$ gzip -d okome.tgz
$ tar -xvf okome.tar
```

##sed
sedは別でまとめたほうが良さそう。sとgの意味がわからなかったので一旦メモ書き。
sで置換する。gを付与すると全置換。付けないと先頭行のみが対象になる。

```
s/置換前の文字列/置換後の文字列/g
```

##env
bashはprintenvじゃなくてenvで同等の結果が得られる。
パイプでsortするとアルファベット順で出力される。

```
$ env | sort
```

##参考文献
[Linux標準教科書](https://linuc.org/textbooks/linux/form.php)

[入門UNIXシェルプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80UNIX%E3%82%B7%E3%82%A7%E3%83%AB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E2%80%95%E3%82%B7%E3%82%A7%E3%83%AB%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6UNIX%E3%81%AE%E4%B8%96%E7%95%8C-%E3%83%96%E3%83%AB%E3%83%BC%E3%82%B9%E3%83%BB%E3%83%96%E3%83%AA%E3%83%B3/dp/4797321946/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E5%85%A5%E9%96%80UNIX&qid=1557131221&s=gateway&sr=8-1-spell)