OmniAICreator/Qiita-1.07M huggingface dataset:
【Flutter】firebase_admob を入れたら出てきた Unable to merge dex エラーの解決

Flutterでadmobを使ってみようと、[firebase_admob](https://pub.dartlang.org/packages/firebase_admob)を入れたら以下のエラーが出てビルドできなくなりました。

```
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'.
> java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
```
ググったらすぐに解決法が出てきました。

Flutterプロジェクトの`android/app/src/build.gradle`に`multiDexEnabled true`を追加します。

```gradle
...

android {
    ...

    defaultConfig {
        ...

        multiDexEnabled true
    }
    ...
}

```

# 参考

["Unable to merge dex" error with firebase_admob package · Issue #14874 · flutter/flutter](https://github.com/flutter/flutter/issues/14874)
Atomの設定ファイルをDropboxに置いて複数端末で共有する方法


# 概要
Atomの設定ファイルをDropboxに配置してシンボリックリンクを貼ることで、複数端末のAtomで同じ設定を利用することが可能です。開発環境が変わるといつも設定するので備忘録として残しておきます。

# 手順
## Atom設定ファイルをDropboxに移動する。
ディレクトリ「.atom」をDropboxの好きな場所に移動する。

```terminal
$ mv ~/.atom ~/Dropbox/xxxx
```

## Atom設定ファイルのシンボリックリンクを作成する。
Dropboxに移動したディレクトリ「.atom」のシンボリックリンクを作成する。

```terminal
$ ln -s ~/Dropbox/xxxx/.atom ~/.atom
※Windowsの場合
$ mklink /D "C:\Users\ユーザー名\.atom" "C:\Users\ユーザー名\Dropbox\xxxx\.atom"
```

## 動作確認(別端末でAtom設定ファイルを利用)
Atomの設定ファイルがDropbox上にあるので、別端末からシンボリックリンクを作成して利用することが可能です。

### 利用したい端末でAtomをインストールする。
※利用したい端末にインストール済みのAtomが存在する場合、完全にアンインストールしておいたほうがいいかもしれません(Atomの関連ファイルが悪さして挙動がおかしくなるかも、、、)。
[Atomエディタを完全にアンインストールする(Mac)](https://qiita.com/happy41111/items/9467473e5562ba940c65)

### 初期配置されている設定ファイルは削除する。

```terminal
$ rm -r ~/.atom
※Windowsの場合
C:\Users\ユーザー名\.atom
```

### Atom設定ファイルのシンボリックリンクを作成する。

```terminal
$ ln -s ~/Dropbox/xxxx/.atom ~/.atom
※Windowsの場合
$ mklink /D "C:\Users\ユーザー名\.atom" "C:\Users\ユーザー名\Dropbox\xxxx\.atom"
```

※ Windowsでシンボリックリンクを作成する場合、「管理者として実行」からコマンドプロンプトを立ち上げておく必要があります。

# 参考
[Atom設定ファイルをDropboxに置いて共有する方法](http://vdeep.net/atom-dropbox)
EthereumのDapps開発にはRemixが便利

#開発フロー
Ethereumで開発を行う際、基本的には次のような流れで実装を行っています。

1. Solidityを利用し、スマートコントラクトを作成
2. Ganecheでローカルの仮想環境を立ち上げ
3. Truffleでコンパイル
4. Reactでフロントエンドを開発
5. 必要とあらばサーバーも開発

Ethereumでの開発手法は様々ですが、Remix, Truffle, Ganacheの組み合わせで特にストレスを感じることなく開発ができているので、個人的には気に入っています。

そんなRemixの布教を兼ねて、初めての方向けに簡単な使い方を記します。

#SolidityでHello World!
Solidityは、Ethereum上で実行できるスマートコントラクを実装するためのプログラミング言語です。Solidityをコンパイルすることで、Ethereum Virtual Machine（EVM）上で走るバイトコードが生成されます。

Remix上ではこのコンパイルと仮想環境でのテストが一気通貫でできます。

まずはRemixを開いてみましょう。

https://remix.ethereum.org/

<img width="1280" alt="Remix_-_Solidity_IDE.png" src="https://qiita-image-store.s3.amazonaws.com/0/101701/1b311f60-f7bc-aad4-a99c-b023e09a0ac1.png">

すでに

- ballot.sol
- ballot_test.sol

の二つがあります。

これは投票アプリのサンプルになります。
詳しい解説は今回は省略しますが、気になる場合には、より詳細なコメントが入ったチュートリアルとして下記公式ページを参考にしてください。

http://solidity.readthedocs.io/en/latest/solidity-by-example.html#voting

新しくファイルを作成する場合には左上の「+」ボタンをクリックします。
ファイル名を「HellorWorld.sol」としてOKを押しましょう。

<img width="1305" alt="Remix3.png" src="https://qiita-image-store.s3.amazonaws.com/0/101701/a011f9c6-b569-8b8b-f038-2e6a2e1bde97.png">

すると真っ白なページが追加されますので、以下のコードを記述します。

```c#:HelloWorld.sol
pragma solidity ^0.4.0;

contract HelloWorld {
    string greeting = "HelloWorld";
    
    function sayHelloWorld() public view returns(string) {
        return greeting;
    }
}
```

「Compile」タブから「Start to compile」をクリックし、黄色や赤色のエラーが出なければコンパイル成功です。

<img width="1302" alt="Remix5.png" src="https://qiita-image-store.s3.amazonaws.com/0/101701/c8bf382a-8c83-7862-b177-7c69a3af5991.png">

コンパイルが完了したら、「Run」タブから、「Deploy」を行います。
少し待ってDeployが完了すると「Deployed Contracts」に今しがた作成したHelloWorldコントラクトが追加されます。

そのタブを展開し、「sayHelloWorld」ボタンをクリックして関数を呼び出します。

<img width="1280" alt="Remix8.png" src="https://qiita-image-store.s3.amazonaws.com/0/101701/a4bd3d6e-3501-b06e-7192-1bb8e2ee0f55.png">

すると「sayHelloWorld」ボタンの下に「0: string: HelloWorld」と結果が表示されます。

:raised_hands:　:tada:　おめでとうございます！　:tada:　:raised_hands:
Gitの基本コマンド

自分用メモ
# git とは？

- 変更履歴を記録・追跡するための分散型バージョン管理システム
- ファイルや変更の履歴などを保存する場所を「リポジトリ」と呼び、分散型のGitはこれを複数持ち管理することができる。
- 対照的なものとして、集中型バージョン管理システムの「SVN」がある。

# gitの基本コマンド集

## リモートからローカルにcloneする

```
git clone
```

##  gitの状態を確認する

```
git status
```
## add(ステージングにあげる)

```
git add
```

* 変更点を確認してaddする(ステージングにあげる)

```

git add -p
```

* 変更したものを全てステージングにあげる

```
git add .
```

* addしたものをアンステージングする

```
git reset HEAD ファイル名
```
* addしたものを全てアンステージングする

```
git reset HEAD
```

## コミット

```
git commit
```

* コメント付きでコミットする

```

git commit -m コメント

```

* コミットを取り消す

```
git commit --amend
```

## ログを確認する
commitしたらログを見てきちんと反映されているか確認する

```
git log
```

## gitにpushする
```
git push origin ブランチ名
```

## ブランチ
- ブランチを切る

```
git checkut -b ブランチ名
```

* ブランチの切り替え

```
git checkout ブランチ名
```

* 今どこのブランチにいるか確認

```
git branch
```

* ブランチを削除

```
git branch -D
```


## 差分を確認
```
git diff ファイル１ ファイル２
```

## 変更したファイルを変更前の状態に戻す

```
git checkout ファイル名
```


## 最新のmasterを適用する

コンフリクトが起こらないように、差分がある場合git stash する


```

git fetch origin master

git rebase FETCH_HEAD

```
オブジェクト指向：クラスとインスタンスについて

#オブジェクト指向とは
「モノ」を組み立てるように表現して、コンピュータに動作させること

#インスタンスとは
クラス⇒枠組み
インスタンス⇒クラスに実際にデータを格納したもの
クラスという設計図をもとに実体を作成する

料理で例えると・・・
クラス⇒レシピ
インスタンス⇒レシピをもとに作られた料理

#クラスの継承
クラスのプロパティを他のクラスを引き継ぐ、

#クラスの中身

```
class Tire{//クラスの定義
//変数の定義
public $weight;
public $size;

//関数の定義
public function _constract($weight,$size){
   $weight=$this->weight;
   $size=$this-$size;

public function tireData($weight,$size)
 {
    echo "重さは".weight."kgです。大きさは".$size."cmです" 
"文字列".変数."文字列"
```
これによって
タイヤの重さ・大きさなどの構造を設計し、出力する準備が整った、だがまだ準備しただけで実際に出力はされない
#インスタンスの中身

```
$tire=new Tire();//Tireクラスのコピー（インスタンスを作成）

$tire->tireData(15,20);//タイヤの重さは15kg,大きさは20cm
```
インスタンスの実行により実体となる
#名前空間の指定方法
場所\クラス名: :メソッド
【動けばいい人用】DockerでPostgresを立ててローカルでEC-CUBE4を動かす

サクッと開発を始めたい人へ

## SQLite3で動かしてみよう

まずは[公式ドキュメント](http://doc3n.ec-cube.net/quickstart_install)に従ってSQLite3で動かしてみよう。

## Dockerのイメージとってきます。

```shell
docker pull postgres:9
```

## Dockerを起動します。

```
docker run --name eccube -p 5432:5432 -e POSTGRES_USER=dev -e POSTGRES_PASSWORD=password -d postgres:10
```

## EC-CUBEにDBの接続情報の設定をします。

`.env` ファイルの `DATABASE_URL` を書き換えます。

```env:.env
DATABASE_URL=postgresql://dev:password@127.0.0.1:5432/eccube
```

## EC-CUBEをインストールします。

```shell
bin/console e:i -n
```

## サーバを起動します。

```shell
bin/console s:r
```

## アクセスします。

http://127.0.0.1:8000/
Marketo データをRDB(MySQL) にレプリケーション（CData Sync）

マーケティングオートメーションのMarketo のデータをDB にレプリケーションします。

DB にレプリケーションしておくと、BI での分析やカスタムアプリケーションでMarketo データを扱うことが容易になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/c2c5132e-16e5-faaa-10d5-1a61f859987d.png)

#CData Sync のダウンロード
[https://www.cdata.com/jp/sync/](https://www.cdata.com/jp/sync/)からData Sync をダウンロードします。Windows 版とJava/Linux 版があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/c4802461-05d7-a120-c5dc-5ba93720210c.png)

Marketo Sync のライセンスを入れます。30日の無償評価版があります。
![スクリーンショット (1235).png](https://qiita-image-store.s3.amazonaws.com/0/116843/79a83b5b-989e-d5c6-e683-a036ba2ed670.png)

#Marketo とData Sync を接続
「接続」タブを開き、「Source」からMarketo アイコンを選択します。

![スクリーンショット (1220).png](https://qiita-image-store.s3.amazonaws.com/0/116843/5c7de070-e893-01de-5600-003e68788dcf.png)

接続設定画面で、Marketo のREST Endpoint, OAuth Client Id, OAuth Client Secret を入力します。
入力後設定を保存し、テスト接続を行います。

![スクリーンショット (1219).png](https://qiita-image-store.s3.amazonaws.com/0/116843/f3c9c0f4-5f15-13c8-1eb0-7f584bd8a990.png)

#同期先のMySQL を接続
MySQL 側には空のDB を作成しておきます。
Data Sync がスキーマを生成してくれるので、空のDB で大丈夫です。
「接続」タブの「Destination」にMySQL の接続設定をします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/e1621d74-aa61-ec79-af0f-edf3cb9db4b5.png)

#同期するデータの選択とジョブ起動設定
「ジョブ」タブから同期ジョブの設定を行います。
ソースをMarketo の接続に、同期先をMySQL の接続に設定します。
「テーブルを追加」をクリックし、表示されるテーブル・ビューのリストから同期するものを設定します。すべてを同期することも可能です。

保存後、手動で「実行」をクリックして、同期を行うことも可能ですし、「スケジュール」でタイマー起動を設定することも可能です。

![スクリーンショット (1239).png](https://qiita-image-store.s3.amazonaws.com/0/116843/96656eaf-650c-cb1c-d7e8-3665ece6a57b.png)

#同期結果を確認
MySQL のワークベンチで、確かにMarketo データが同期されていることを確認します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116843/c638b54b-8e2a-c514-3c84-b1c694937f05.png)


（おわり）
Raspberry Pi3とDACでサウンド再生環境を整える

# はじめに
ラズパイに接続できるDACを購入したので環境構築のメモ。

# 実機環境
* CPUボード
    * RaspberryPi3
    * SDカード16GB
* DAC
    * Kuman サウンドカード モジュール SC08C
    * https://www.amazon.co.jp/gp/product/B01HCUBRHA/ref=oh_aui_detailpage_o05_s00?ie=UTF8&psc=1

# 開発環境
Ubuntu 16.04

# OSのインストール
## イメージの入手
DACを使うため、初めからDACをサポートしていると思われるvolumioをチョイス。

https://volumio.org/get-started
よりイメージファイルをダウンロード

## イメージの書き込み
```
sudo dd if=volumio-XXXXX-pi.img of=/dev/sdx bs=32M
```
書いたSDカードをラズパイに挿せばあっさりとOSが立ち上がる。

# 設定
## 使うDACを選択
HiFiBerry DAC Plusを選択

## ssh有効化
外部のブラウザからhttp://volumio/dev/にアクセス
SSHをenableにする

## パーティションの容量拡張
デフォルトでboot/volumio/volume_dataの３つのパーティションがある。

```
/dev/sda1 61M 37M 24M 61% boot
/dev/sda2 2.2G 544M 1.6G 27% volumio
/dev/sda3 262M 209M 33M 87% volumio_data
```
この中でrootfsとして使われるのはvolumio_dataだが、最初から87%も使われている状態。SDカードは16GBのものを使ったが、すべては使われていないようなので拡張する。

```
sudo e2fsck -f /dev/sda3 
sudo resize2fs /dev/sda3
```

以下のようにvolumio_dataの容量が大きくなる。

```
/dev/sda1 61M 37M 24M 61% boot
/dev/sda2 2.2G 544M 1.6G 27% volumio
/dev/sda3 13G 210M 12G 2% volumio_data
```

# その他メモ
## サウンドファイルの正式な置き場
localに場合は/mnt/INTERNALに置くのがいいみたい。

```
volumio@volumio:/var/lib/mpd/music$ ls -l
total 0
lrwxrwxrwx 1 root root 13 Jul 26 14:22 INTERNAL -> /mnt/INTERNAL
lrwxrwxrwx 1 root root  8 Jul 26 14:22 NAS -> /mnt/NAS
lrwxrwxrwx 1 root root  8 Jul 26 14:22 USB -> /mnt/USB
```
## aplay

```
aplay -D plughw:1 Front_Center.wav
```
*)環境によってplughw:1の部分は変わる
## arecord

```
arecord -D plughw:5 test.wav
```
*)環境によってplughw:5の部分は変わる
goでssh config設定を忘れてもsshできるようにした

こんにちは。かなり久々に書きます。

今は割と大きめの会社でSREをメインにやっていて、
パフォーマンス改善だったり、監視項目の整理・追加etcをしています。
昔はサーバサイドをメインでやっていて、その後android/iosアプリ開発、react+reduxとかやっていました。


今回のエントリーはsshコマンドでログインする際に基本的にconfigに鍵のパスとかを設定して後は、`ssh Host名`とかでログインするのが一般的かと思います。
ただそのconfigが増えてくると、Hostの名前を何にしたか忘れてしまってわざわざconfigの中身を表示するとかめんどいなーと思い、
今回はgoでいつもssh configの名前を忘れてしまう問題をOSSで解決してみました。
コードのアドバイスでも編集依頼でもなんでもいいので、何かありましたらコメントください！！

## github
https://github.com/revenue-hack/homebrew-sshcut

## インストール
### brew

```
brew tap revenue-hack/sshcut
brew install sshcut
```

### go get

```
go get
go get github.com/revenue-hack/homebrew-sshcut
```

## 使い方
.ssh/configの中身が

```
Host test
HostName 11.111.11.111
User test
Port 21
PreferredAuthentications publickey
IdentityFile ~/.ssh/test.pem
Host test1
HostName 22.222.22.222
User test2
Port 21
PreferredAuthentications publickey
IdentityFile ~/.ssh/test2.pem
```

な感じで、Hostが正しく記載されていて、
本来のやり方通り

```
ssh test
```

みたく`ssh+Host`でログインできれば使えます。

使い方は
`sshcut`とコマンドを叩くと

```
number	Host
0	test
1	test1
select ssh host number?:
```

のようにHostごとにnumberが振られているので、
後はnumberを選んでenterをするだけで、ログインできます。


## コードの簡単な説明

コードは単純でmain.goのみでできています。

main関数のはじめにやっていることは、
configパスから、configファイルを読み込んでいます。

```
configFilePath, err := getConfigFilePath()
if !err {
	fmt.Println(".ssh config file nothing Error")
	os.Exit(1)
}
```

実際にファイルを読み込んでいるのはreadFile関数です。

```
func readFile(configFilePath string) (HostList, bool) {
file, err := os.Open(configFilePath)
	if err != nil {
		fmt.Printf("%s is not exist\n", configFilePath)
		os.Exit(1)
	}
	defer file.Close()
	reader := bufio.NewReaderSize(file, 4096)
	var hosts HostList
	for {
		line, _, err := reader.ReadLine()
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Println("can't read config file")
			panic(err)
		}
		host, hasHostObject := objectMapping((string(line)))
		if !hasHostObject {
			continue
		}
		hosts.Hosts = append(hosts.Hosts, host)
	}
	if hosts.Hosts == nil {
		return hosts, false
	}
	return hosts, true
}
```

その際に、objectMapping関数でやっているのはすでにssh configはログインできる前提で、Host情報だけをマッピングしています。

```
func objectMapping(fileArgs string) (Host, bool) {
	var alias Host
	if strings.Contains(fileArgs, "Host ") {
		args := strings.Fields(fileArgs)
		if len(args) != 2 {
			return alias, false
		}
		alias.Alias = args[1]
		return alias, true
	}
	return alias, false
}
```


main.goの２１行目で、Hostが正しく存在したら、その一覧を表示しています。

```
fmt.Printf("%s\t%s\n", "number", "Host")
for i, host := range hosts.Hosts {
	fmt.Printf("%d\t%v\n", i, host.Alias)
}
fmt.Printf("%s", "select ssh host number?: ")
```

27行目からは、ユーザのnumber入力があった場合の処理を記述していて、39行目で、実際にコマンドを実行しています。

```
stdIn := bufio.NewScanner(os.Stdin)
if stdIn.Scan() {
	text := stdIn.Text()
	key, err := strconv.Atoi(text)
	if err != nil {
		fmt.Println("select ssh host number must be integer")
		os.Exit(1)
	}
	cmd := exec.Command("ssh", hosts.Hosts[key].Alias)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err = cmd.Run(); err != nil {
		fmt.Println("can't ssh connection")
		panic(err)
	}
}
```

以上です。
何かの参考になればと思います。
Ionicでibeaconを使ったアプリを作る

IonicでiBeaconを利用したアプリを作るためにはCordovaのibeaconプラグイン（cordova-plugin-ibeacon）をtypescriptでラップしたモジュールを利用する必要がある。
詳細はionicの下記ページに記載してある。
https://ionicframework.com/docs/native/ibeacon/

1. プロジェクト配下で以下のコマンドを実行する

    ```
    ionic cordova plugin add cordova-plugin-ibeacon
    npm install --save @ionic-native/ibeacon
    ```
1. app.module.tsに以下を追加

    ```TypeScript
    ...

    import { IBeacon } from '@ionic-native/ibeacon';

    ...

    providers: [
      StatusBar,
      SplashScreen,
      IBeacon,
      {provide: ErrorHandler, useClass: IonicErrorHandler}
    ]
    
    ...
    ```

3. 対象のクラスのimportとConstructorとmethodを追加

    ```TypeScript
    ...
    import { IBeacon } from '@ionic-native/ibeacon';
    ...
    export class ConfigPage {
      delegate:any;
      region:any;
      constructor(public navCtrl: NavController, private ibeacon: IBeacon) {
      }
      startScan(){
        console.log("initScanner!");
        this.ibeacon.requestAlwaysAuthorization()
        this.ibeacon.requestWhenInUseAuthorization()
        
        this.delegate = this.ibeacon.Delegate()
        this.delegate.didChangeAuthorizationStatus().subscribe(data=>console.log('didChangeAuthorizationStatus has completed', JSON.stringify(data)))

        this.delegate.didRangeBeaconsInRegion().subscribe(data => {
            console.log('didRangeBeaconsInRegion:', JSON.stringify(data,null,4))
            // console.log(data.beacons[0].rssi);
          },
          error=> console.log('didRangeBeaconsInRegion Error: ', error))

        this.delegate.didStartMonitoringForRegion().subscribe(data=>console.log('didStartMonitoringForRegion:',JSON.stringify(data),error=>console.log(error)))
        this.region = this.ibeacon.BeaconRegion('test.beacon','B9407F30-F5F8-466E-AFF9-25556B57FE6D');

        this.ibeacon.startMonitoringForRegion(this.region).then(
          () => console.log('Native layer received the request to monitoring:',JSON.stringify(this.region)),
          error => console.log('Native layer failed to begin monitoring: ', error))

        this.delegate.didEnterRegion().subscribe(data => {
            console.log('didEnterRegion: ', data);
        });

        this.delegate.didExitRegion().subscribe(data => {
          console.log('didExitRegion: ', data);
        });
      }
    }
    ```

1. 実行する
    
    ```
    ionic cordova run android --device
    ```

1. methodを実行するとdidEnterRegionとdidExitRegionがバックグラウンドから呼ばれるようになる。

> デバッグをするときは、実行中にchromeのアドレス欄にchrome://inspect/#devicesを入れて画面下部のinspectボタンを押すとchrome上でできるようになる。
ターミナル使ってみた🔰

# ターミナル使ってみた🔰
Fjord Boot Camp のプラクティスでやったことをまとめます！
基本的なコマンド( https://qiita.com/sakki1223/items/182c5498de0251eff07b )は、割愛。

#音声合成ソフトウェア　使ってみた🎤

##使ったソフトウエア

 - say
    - OS Xに付属の音声合成ソフトウェア
    - Siriの声によく似ている
 - [SayKana](https://www.a-quest.com/quickware/saykana/)
    - Mac OS X上で動作する日本語音声合成ソフトウェア。say コマンドと同様の機能を実装
    - mlオプションで男性の声も実行できる

#実行！！

<img width="568" alt="sakki_—_-bash_—_80×24.png" src="https://qiita-image-store.s3.amazonaws.com/0/216761/bb6660e2-a852-3090-7c53-912400407630.png">

いろいろしゃべらせてみましたが、これが一番親しみがあるように聞こえました。

※oオプションで保存ができる
※oオプションを実行するときはしゃべってくれないが、文字列だけにすればしゃべってくれる。（もちろんファイルを実行してもしゃべってくれる。）



# Package Manager　使ってみた🎒
##使ったソフトウェア

 - [Homebrew](https://brew.sh/index_ja)
    - Homebrewには、Xcodeのインストールが必要。
        - Apple Developer登録が必要
    
## パッケージ内のソフトのインストールを実行！！
treeをインストール。
ソフト名だけでインストールできる。
<img width="578" alt="sakki_—_-bash_—_80×24.png" src="https://qiita-image-store.s3.amazonaws.com/0/216761/261d1c80-6909-c39b-25dc-e21692f6ede1.png">


#`#!`(shebang)　使ってスクリプト実行してみた❗️
`#!`(shebang)については[こちら](https://qiita.com/sakki1223/items/182c5498de0251eff07b#shebang)
##使ったファイル
 - ファイル名
    - echo-hello
 - スクリプト
    - ＃!/bin/sh ↩︎ echo hello ↩︎
 - コマンド
    - /Users/sakki/echo-hello

※sh...インタプリンタ（スクリプトを実行する種類のプログラム）
 
##実行！！
<img width="603" alt="sakki_—_-bash_—_80×24_と_「ターミナル使ってみた🔰」を編集_-_Qiita.png" src="https://qiita-image-store.s3.amazonaws.com/0/216761/0508e952-dd17-661e-740a-bff4a4d06c91.png">

`echo hello`に`/bin/sh`が渡された！！

##所感
GUIは後からついてくるもの。
つまり、ターミナルでできてGUIではできないことはたくさんある。
ターミナルが扱えるようになれば、GUI頼みではなくなり、できることの幅が広がる！！
ターミナルってすごい！楽しい！以上！笑
bitbucketとJenkinsを連携し自動テストとデプロイの設定

#やったこと
bitbucketとJenkinsを連携して、自動テスト、デプロイの設定をしてみました。

・bitbucketにプッシュしたら、jenkinsのテストが動き出す。
・jenkinsのテストが問題なければ、デプロイする。

参考サイト
http://miraicraft.co.jp/blog/2014/08/20/bitbucket_jenkins/

#1 bitbucketとJenkinsを連携する公開鍵を作成する
```
$ sudo usermod -d /var/lib/jenkins -s /bin/bash jenkins
$ cd /var/lib/jenkins
$ sudo -u jenkins ssh-keygen
```

#2 Bitbucketに公開鍵を登録する
Bitbucketの 設定 > アクセスキー > 「鍵を追加」 をクリック。
Keyの所にさっき生成した公開鍵(/var/lib/jenkins/.ssh/id_rsa.pub)の内容をコピペ
Labelも適当に入力
で「鍵を追加」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/266541/16e059b7-b1a3-e6ed-39e5-4f6f585d1467.png)

#3 Bitbucketでフックの設定
Bitbucketの 設定 > Webhooks > 「Add Webhook」をクリック。
URLに
http://(jenkinsのurl)/git/notifyCommit?url=git@bitbucket.org:xxx/zzz.git(xxx/zzzは自身のbitbucketのurl)
を入力
Titleも適当に入力
![image.png](https://qiita-image-store.s3.amazonaws.com/0/266541/7c4605f5-6de0-5674-67db-5801696b81ce.png)

#4 jenkinsでテスト用jobの設定
ダッシュボード > 新規ジョブ作成
ジョブ名を適当に入力し、「フリースタイル・プロジェクトのビルド」を選択
「ソースコード管理」で「git」を選んで
「リポジトリ URL」に「git@bitbucket.org:xxx/zzz.git」を入力

※URLを入力した際、初回はエラーがでるため、コンソールから、以下のコマンドなど実行して
.sshのknown_hostsにBitbucketを追加しておく。途中の質問にはyesを入力する。

```
$ git ls-remote -h git@bitbucket.org:xxx/zzz.git
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/266541/0583eb4e-5571-fce5-8b4f-ab3f45e8ff95.png)

「ビルド後の処理の追加」> 「他のプロジェクトのビルド」でこの後作成するデプロイ用のjob名を入力
![image.png](https://qiita-image-store.s3.amazonaws.com/0/266541/057cf325-9cc1-4ef8-382f-bc60b10a56d4.png)

#5 jenkinsでデプロイ用jobの設定
ダッシュボード > 新規ジョブ作成
ジョブ名を適当に入力し、「フリースタイル・プロジェクトのビルド」を選択
「ビルド手順の追加」> 「シェルの実行」でビルド用のシェルを実行するよう設定
デプロイシェルは、/var/lib/jenkins/workspace/(ジョブ名)に配置
![image.png](https://qiita-image-store.s3.amazonaws.com/0/266541/9029a0e7-adf1-1b56-7030-e8abda8cf89d.png)


以上で、bitbucketにプッシュしたらjenkinsのテストと問題なければデプロイが動く設定ができました。
rewriteとシンボリックリンクの違い

Webサーバーにおいて、Rewriteとシンボリックリンクは、URLを転送し実ファイルの場所が別のものになる点では同じである。しかし、プログラミングの際には、注意するべき点もある。この記事では両者の違いについてまとめ、Debian stretchでApacheをつかった場合の検証結果を示す。

#相違点一覧
rewriteとシンボリックリンクの違いを表にした。詳細は次節に記述する。

||rewrite|シンボリックリンク|
|---|---|---|
|カレントディレクトリ|転送先|転送元|
|正規表現|使える|使えない|
|Webサーバー|依存する|依存しない|
|Gitでの管理|.htaccessの管理|できる|

#カレントディレクトリ
次の構成のWebサイトで検証を行った。

|用途|url|ファイルシステム上の位置|
|---|---|---|
|直接|/|/var/www/html/|
|リライト|/rewrite|/var/www/html/rewrite|
|シンボリックリンク|/link|/var/www/html/link|


このWebサイトにテストの用のPHPを『直接』に設置した。次に『リライト』にはファイル.htaccessでrewrite設定を、『シンボリックリンク』には、ln -sコマンドでシンボリックリンクを設置した。最後に、Webブラウザからアクセスし、それぞれのカレントディレクトリの既定値を出力した。

```PHP:/var/www/html/test.php
<html>
<body>
<?php
echo __DIR__;
echo "<br>";
echo getcwd ();
?>
</body>
</html>
```

```:/var/www/html/rewrite/.htaccess
RewriteEngine on
RewriteRule ^test\.php$ /test.php [L]
```

 - 結果

|方法|URL|出力|
|---|---|---|
|直接|/test.php|/var/www/html<br>/var/www/html|
|rewrite|/rewrite/test.php|/var/www/html<br>/var/www/html|
|シンボリックリンク|/link/test.php|/var/www/html<br>/var/www/html/link|

この結果から、rewriteはURLとファイルシステムの関係を書き換えているが、シンボリックリンクはファイルへの別名になっていることがわかる。

#Gitでの管理
Apacheの場合、Rewriteの設定は.htaccessにも記述できるので、Gitでも管理することができる。nginxでは、.htaccessがないので直接管理することはできない。

#考察
ファイルを複数のURLで共有する場合にはシンボリックリンクを使用し、URLを遷移させる場合にはRewriteを使用する。プログラミングでシンボリックリンクを使う場合は、カレントディレクトリが変わることに注意して欲しい。

#追記
@error_401 様より、PHPにおけるシンボリックリンクの重要な注意点についてコメント頂いた。詳しくは下のコメント欄を参照のこと。
Firefox の Headless モード  (Node.js)

次のページと同じことを、Node.js で行ってみました。
[Firefox の Headless モード (python3)](https://qiita.com/ekzemplaro/items/77432a30212b788d56d1)
まだ、Javascript の実行が出来ていません。timeout の調整が必要です。

```js:headless_firefox.js
// ---------------------------------------------------------------
//	headless_firefox.js
//
//						Aug/13/2018
//
// ---------------------------------------------------------------
const fs = require('fs')

const { Builder, By, Key, promise, until } = require('selenium-webdriver')
const {promisify} = require('util')

const webdriver = require('selenium-webdriver')

const firefox = require('selenium-webdriver/firefox')
promise.USE_PROMISE_MANAGER = false

var firefoxOptions = new firefox.Options()
firefoxOptions.setBinary('/usr/bin/firefox')
firefoxOptions.headless()
const driver = new Builder()
.forBrowser('firefox')
.setFirefoxOptions(firefoxOptions)
.build();


// ---------------------------------------------------------------
async function main()
{
	const url_target='https://ekzemplaro.org/storytelling/'
	await driver.get(url_target)
	await driver.wait(async () => {
	const readyState = await driver.executeScript('return document.readyState');
	return readyState === 'complete';
  });
	const data = await driver.takeScreenshot();
	await promisify(fs.writeFile)('screenshot.png', data, 'base64');
	await driver.quit();
}

// ---------------------------------------------------------------
main ()
// ---------------------------------------------------------------
```

実行方法

```
node headless_firefox.js
```

>screenshot.png が作成されます。

実行結果
![screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/179446/f51500fc-d10d-6a0a-7847-a7c3901708c7.png)
HTML・CSS講義アウトプット

#講義で気になったとこと・アウトプット

- table　は表
- <th>でタイトル　<tr>が一つの行<td>がデータ
- マージンとパディングの違いに注意
    - 箱の外と内のイメージ
- サイト設計を固めてからコードを書く
    - 誰がみてもわかるように　区切りを意識して　無駄なく整理整頓されたコード
- lessを使ってhtmlを書く


##LESSの書き方

- LESSは変数を使える
- lessc　styles.less（LESSファイルの名前） styles.css（新たに作ったCSS）を作成すると勝手にCSSに変換してくれる
- lessファイルを書いて変換し、CSSを使う
- 例）h1が24pxでh2はh1の大きさよりも4小さくしたい
    - h1=24pxで定義してh2=h1-4で定義する
- 階層的な書き方ができる
- ミックスイン：共通の部品をまとめられる
セキュリティ関連文書　サイトまとめ

現在、セキュリティ文書関連の作成を行っており、それらの参考となるセキュリティに関連する文書が記載されたサイトをまとめておきます。


[情報セキュリティ基礎](http://isc.iwasaki.ac.jp/monka_itaku/info-security_kyokasyo.pdf)

[経済産業省資料-セキュリティ関連コンテンツ](http://www.meti.go.jp/policy/netsecurity/secdoc/secdoc_list.html)

[CISOハンドブック](https://www.jnsa.org/result/2018/act_ciso/)

[OWASP Secure Coding Practices](https://www.owasp.org/index.php/OWASP_Secure_Coding_Practices_-_Quick_Reference_Guide)

[OWASP ASVS 3.1](https://www.owasp.org/index.php/Category:OWASP_Application_Security_Verification_Standard_Project#tab=Home)

[OWASP ASVS 3.0.1（日本語）](https://www.jpcert.or.jp/securecoding/OWASP_ASVS_20160623.pdf)

[OWASP　Secure Coding Cheat Sheet](https://www.owasp.org/index.php/Secure_Coding_Cheat_Sheet)

[JPCERT　セキュアコーディング資料](https://www.jpcert.or.jp/securecoding/)

[安全なWebサイトの作り方](https://www.ipa.go.jp/security/vuln/websecurity.html)
ローカル・ステージング・プロダクション

## 理想
開発者は、自分のローカルで、プログラムに対する変更を試してみます。
いわば開発環境になります。そこで試してみてから、行けそうな気がしたら、
その変更をステージングサーバにまで持っていきます。デプロイって言うでしょう。
この時、ステージングってのは、あくまで本番のテスト環境になります。
スペックも設定もいくつか違うのがありますが、OSやミドルウェアのバージョンなどが基本的に揃っていて、
本番に適用したい変更の全てを、この環境でテストすることになります。

なので、教科書ではいつも、「ステージング＝プロダクション」を前提として設定しています。
僕もそう教えてもらいました。

## 現実は？
違う。違う。めちゃめちゃ違います。
基本的な構成が一緒だとしても、ステージングって、一人で使う環境じゃないので、環境が想定と違う場合がありえます。

他の開発者が試しで作って、テストが終わっても、そのまま放置したりすることが十分あり得るからです。
プロダクションとステージングがまったく一緒だという想定の上で行われたステージングテストって、実際プロダクションでは
どれぐらい意味があるのでしょうか。

そもそも想定って、エンジニアにとってはかなり怖いことかも知れません。想定ってのは、あくまで人間、詳しく言えば思考の主体として人間が
無意識的に決めている、他人とは共有できない自分だけの思考の枠である恐れがあるからです。
誰もバグを望んでいないです。意図したバグってありえないです。じゃ、なんでバグが発生するのか？そこが人間の想定って認識の死角です。

例えば、プロダクションの環境では、定期的にクーロンが動ぎ、別のサーバからデータの同期してくると考えてみましょう。
ステージングでもそういう定期的なジョブが設定されているでしょうか？
されてなかったら、その時点でアウトですね。しかも、ステージング上はテストのために、人間が手動でデータをベッドのディレクトリ転送したりする仕組みであれば、もうその時点で、真のテストは難しくなるかも知れません。

## どうすべきか？
ローカルは置いといて、ステージング環境でのテストが、本番のテストにならない。なら、ステージングとプロダクションの環境って、
そもそも違うってことを常に意識するのが答えになるんじゃないかなと思います。

特定のモジュールを修正するプロジェクトがあるとしたら、最初の見積もりとして、両環境の差を確認する課題を用意したらどうでしょうか。
かなりプロジェクトの進捗に影響を及ぼすかも知れません。

１．ファイルやディレクトリ構成は同一なのか。
２．モジュールのバージョンは同一なのか。
とかを事前に考えてみて、想定ってものの正確さを高めることができるのであれば、リリースの直前発生して、皆バタバタすることになる
原因を、一つでも縮められるのではないでしょうか。
「進化的アーキテクチャ」を読んだよ

こちらです。
https://www.amazon.co.jp/dp/4873118565
まだ発売前ですが、会社でオライリーの定期購読をしているのではやめに入手。わずか200ページですが深い話でした。ソフトウェアシステムを構築/設計する人であればおすすめです。

#　簡単なまとめ
ポイントとなるのは適応度関数(Fitness Function)という概念。
システムが目的をどれだけ達成しているか?という指標を適応度関数という形で表現します。
どういう形で実装するかは本を読んでもらうとして、ちょっとずれるかもしれませんが、ソシャゲ開発者が課金額やMAU/DAUを指標としているように、システム改善のための指標を計測可能な形でつくるという考え方は良いと思いました。

その指標を追えるように、システムは変更がしやすい形につくられる必要があり、そうでないシステムであればどのようにすればよいか? という点が簡潔に書いています。アジャイル開発、継続的デリバリーなどのここ10年くらいの技術をうまくつかった考え方だとおもいました。

ただ、これ読んだから、すぐ素敵なシステムがつくれるかというとそんなことはないので、精進が必要です。

# 面白い言葉

この本で知った面白い言葉がいくつかあったのでメモしておきます。

## 逆コンウェイの法則

「システム構造は、設計する組織の形に従う」
というのがコンウェイの法則ですが、逆とついているのは、
「システム構造のための組織をつくる」
ということで、おもしろかったです。2 pizzaチームなど実際に実践している組織もありますね。

## ホリスティック(holistic)

 全体論的なという意味です。反対語でアトミック(atomic）が使われていました。単一の特性ではなく、現実的で複合的な特性を適用度関数として定義するという文脈で利用されています。単に単語しらなかっただけです。すいません。

## スノーフレーク(snow flake) 

 雪の結晶ではなく、複数のサーバが手作業でそれぞれ微妙に違う設定になってる状態をいうということでした。
 雪は遠くからみると一様ですが、顕微鏡でみると、まったく別の形になってるというところから来ているということで、言い得て妙です。

## 最後に心に響いた言葉をひとつ

「手作業による成果物に執着して不合理になってはならない」

心に刺さる。これを書いた人は真摯にシステム開発にむきあってきたんだろうなと思う本でした。
ちなみに学んだことの1/10くらいしか書いてないので、気になる方は読んでみるとよいかとおもいます。

ではでは。
レガシーなCSSを淘汰する

IEに恨みがある人のための記事です。

## レガシーなCSSとは何か
- 大規模なのにプリプロセッサ、ポストプロセッサを使っていない
- float
- <!--[if lt IE 9]>
- IE対応
- positionで2カラムレイアウト
- 色が管理されていない
- 1ファイルがでかい
- 命名規則がない
- !important地獄
- レイアウトにpxが入っている

##　どうやって淘汰するか

### プリプロセッサ、ポストプロセッサ
- とりあえず導入する
- CSSファイルはそのままSCSSファイルに移動できるのでとりあえず移動する
- PostCSSは.cssのままなのでとりあえずautoprefixerだけ入れる

### float
- flex使う
- 新しいbootstrapを使う

### <!--[if lt IE 9]>
- IE11以前への対応をやめる
- 最新ブラウザへ誘導する
- IE11はautoprefixerで対応する

### positionで2カラムレイアウト
- divをflexで重なる位置に置く => positionに入っている内容を移動する => positionを消す
- flexでレイアウトする

### 色が管理されていない
- SCSSなどで変数を使う
- こんな感じにする。`$color-gray-e1: #e1e1e1;`
- デザインの段階で色数を絞る

### 1ファイルがでかい
- とりあえず雑に分割する
- 分割しまくってあとで統合する

### 命名規則がない
- BEM使う

### !important地獄
- 別ファイルを作って!importantが付いているものをひたすら入れる
- 出現順に依存している場合が多いので、上から順に移動する
- 登場するページを探す => 新規クラスを作って!importantを消す

### レイアウトにpxが入っている
- %, vw, vhにする

## まとめ
レガシーなCSSは見ているだけでストレスがたまるのでなんとかしたいですね。
【Wordpress】サーバ上のソース内の「http://」を「https://」に一括置換(複数ファイルの特定文字(URL)を一括置換)

#はじめに
- WordpressのSSL化をする際に迷ったので備忘録的にまとめます。
    - WordpressをSSL化する際にDBデータやサーバ上のソース内を置換しないといけません。
    - Wordpressでよく使われているツールは大体DBが対象です。
    - サーバ上のファイル内を一括置換したい際はコマンドをうまく組み合わせる必要があります。

#やること
- サーバ上の複数ファイルの中にある特定の文字列(URL)をコマンドで一括置換します。


#コマンド例

**# find <一括置換したい対象ディレクトリ> -type f | xargs sed -i 's/<置換前の文字列>/<置換後の文字列>/g'**

```
# find /var/www/html/ -type f | xargs sed -i 's/http:\/\/example.com\/dir1/https:\/\/example.com\/dir1/g'
```

##注意点
- URLが置換対象の場合、特殊文字と判断されないようにエスケープ文字を入れないといけません。
    - 「http://」は「http:\/\/」にしましょう。
Eclipseで通常のフォルダがソースフォルダに変換できなかった時の話

# Eclipseで通常のフォルダがソースフォルダに変更できなかった時の話

初投稿です。詰まった所とその解決策として使っていきたいなと思っています。
既出の話題でしたら、コメントで補足いただけると幸いです。
今日はEclipse上で「フォルダ（Folder）」と「ソースフォルダ（Source Folder）」に変換できなかった時の話。

## 利用環境

* `maven` 3.3.9
* Eclipse 4.4.2

## 起こった問題

外から入手したソースコードを `mvn eclipse:eclipse` を使ってEclipse上にインポートしようとした時、
何故かソースフォルダでなく、フォルダのままのディレクトリがあることに気づきました。

![20180813-192438.jpg](https://qiita-image-store.s3.amazonaws.com/0/278105/d57bc162-d090-f18f-bb0c-c5a26cecf924.jpeg)

※上の`staticanalysis`がソースフォルダ、下の`sample-folder`が普通のフォルダです。
コマンドを叩いたディレクトリにある`.classpath`以下を参照しても、普通は

```
<classpath>
  <classpathentry kind="src" path="src/test/java" output="target/test-classes" including="**/*.java"/>
  <classpathentry kind="src" path="src/main/java" including="**/*.java"/>
  <classpathentry kind="output" path="target/classes"/>
...
</classpath>
```

となっており、フォルダを作ってEclipse上でF5を押すだけで反映されるはずなのに。
何が良くないのかと思って試行錯誤してみたところ…。


## 解決策

至ってシンプルで、**Eclipse上でフォルダとして認識されない文字が含まれていた**という話でした。
今回の場合、`-`の記号が引っかかっていたようです。
試しに`-`の記号を取り除いてフォルダを作成してみたところ、正しくソースフォルダとして認識されました。

どのようなソースフォルダ名が許されるかは、Eclipse上で調べられます。

![20180813-192853.jpg](https://qiita-image-store.s3.amazonaws.com/0/278105/f27e4c87-7585-3ade-f982-098e02e4335d.jpeg)

今回の場合、`-`って記号がソースフォルダ名としてNGだったみたいですね。
業務の場合、フォルダ名のネーミングルール等ある可能性が高く、このような問題は起こりにくいかもしれません。


## まとめ
内容自体は至ってシンプルですが、困った時の参考になれば、という感じでこれからも投稿していこうと思います。
詰まった時の参考になれば幸いです。
【Unity】Package Managerの実体パスのメモ

# はじめに

この記事は[Unityゆるふわサマーアドベントカレンダー 2018](https://qiita.com/splas_boomerang/items/e6619fb1e6dd92fd231f)の14日目です。
(あと数枠あるので、興味があったらぜひご参加ください)

UnityHubを使っているせいかバージョンのせいか、Winのパスが違っていたのでメモを残しておきます。

# 検証環境

Win: UnityHub 0.18.1 + Unity2018.2.1f1
Mac: UnityHub 0.18.1 + Unity2018.2.1f1

# Package Managerの実体パス

## バイナリファイル

各フォルダ以下にはパッケージ一覧が保存されている。実行時に参照してるのはここっぽい。

`/{PackageName, eg:com.unity.hoge}/{Version}/`以下にある`.tgz`がバイナリファイル。`.unitypackage`は内部的にこの形式らしい。

### Windows

```
~/AppData/Local/Unity/cache/npm/
```

### Mac

```
~/Library/Unity/cache/npm/
```

## ソースファイル

Unity2018.2くらいからUnity Editor上で見れるようになった。実体はここっぽい。
アクセス権がデフォルトで書き込み不可になっていた。

### Windows

```
~/AppData/Local/Unity/cache/packages/packages.unity.com/
```

### Mac

```
~/Library/Unity/cache/packages/packages.unity.com/
```


# 参考

[Unity: Package ManagerからインストールしたPackageのソースコードの場所 - Kilimanjaro Warehouse](https://kiliware.hateblo.jp/entry/2018/07/29/093431)

[Unity Package Managerについて - Qiita](https://qiita.com/k7a/items/cc5d09bc1000551b203f)
Fujitsu ServerViewRAIDManagerをインストールする

RHEL6.10をインストールしてファイルサーバとして運用しているFujitsuのPRIMERGYに対して、
古いバージョンを削除して、新しいServerViewRAID managerをインストールした。

```# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.10 (Santiago)```

```# rpm -qa | grep -i ServerView
ServerView_RAID-6.2-6.el6.x86_64```

# rpm -e ServerView_RAID-6.2-6.el6.x86_64

[  OK  ] ServerView RAID Manager: [  OK  ]
警告:    erase /opt/fujitsu/ServerViewSuite/RAIDManager/bin/libgcc_s.so.1 の unlink に失敗: そのようなファイルやディレクトリはありません
警告: /opt/fujitsu/ServerViewSuite/RAIDManager/bin/amMPX.ini は /opt/fujitsu/ServerViewSuite/RAIDManager/bin/amMPX.ini.rpmsave として保存されました。
警告: /opt/fujitsu/ServerViewSuite/RAIDManager/bin/amDPatch.ini は /opt/fujitsu/ServerViewSuite/RAIDManager/bin/amDPatch.ini.rpmsave として保存されました。

ダウンロードしてきたファイル一覧から対象のバイナリを使ってインストールを実施
# pwd
/home/hoge/RAID/Linux

# ls
ServerView_RAID-6.5-7.el5.i386.rpm    ServerView_RAID-6.5-7.el6.i686.rpm    ServerView_RAID-6.5-7.el7.x86_64.rpm   ServerView_RAID-6.5-7.sles11.x86_64.rpm
ServerView_RAID-6.5-7.el5.x86_64.rpm  ServerView_RAID-6.5-7.el6.x86_64.rpm  ServerView_RAID-6.5-7.sles11.i586.rpm  ServerView_RAID-6.5-7.sles12.x86_6

・ちゃんとインストールできるかtestする
# rpm -ivh --test ServerView_RAID-6.5-7.el6.x86_64.rpm
準備中...                ########################################### [100%]

・実際にインストールする。snmpd.confの修正が入るのでsnmpdデーモンが再起動する
# rpm -ivh ServerView_RAID-6.5-7.el6.x86_64.rpm
準備中...                ########################################### [100%]
   1:ServerView_RAID        ########################################### [100%]
snmpd を停止中: [  OK  ]
snmpd を起動中: [  OK  ]

・インストールされたことを確認
# rpm -qa | grep -i ServerView
ServerView_RAID-6.5-7.el6.x86_64

・以前と違ってRAID Manager用のデーモンを立ち上げなくてもすでにportがあいている！
# netstat -tnl | grep 3173
tcp        0      0 0.0.0.0:3173                0.0.0.0:*                   LISTEN
tcp        0      0 :::3173                     :::*                        LISTEN


LinuxOSのiptablesに許可設定を書いてあげる

-A INPUT -m state --state NEW -i bond0 -p tcp --dport 3173 -j ACCEPT

ウェブブラウザでアクセスしてみる
https://myhostname.mydomain.local:3173

簡易的な場合はroot userでログインして状態確認などをしちゃうが、きっちりuser権限を管理したい場合は、
下記のgroupにLinux Userを登録することで権限を与えられるらしい。

以下マニュアルより抜粋

RAID管理者
「raid-adm」(デフォルト)という名前の新しいユーザグループを作成し、既存のユーザをこのグループに追加することで、ServerView RAID Managerの編集モードへの アクセス権限を持つユーザをセットアップします。
RAIDユーザ 「raid-usr」(デフォルト)という名前の新しいユーザグループを作成し、既存のユーザをこのグループに追加することで、編集禁止モードのユーザをセットアップします。
オブジェクト指向のこころー演習問題(第４部)

以下の問題及び回答は[書籍](https://www.amazon.co.jp/dp/4621066048)を参考に記載しています。また一部引用があります。

# 第12章：エキスパートはどのように設計するのか？
## 基礎
Q1. Alexanderは、優れた設計を特徴付けるため、「活き活きした」という言葉を使用しています。ソフトウェアの場合、どういった用語を使用するのが良いでしょうか？
A1. 堅牢で柔軟なシステム

Q2. 優れた設計を行うには、何を念頭に置いておく必要があるでしょうか？
A2. 全体像またはコンテキスト。


Q3. Alexanderは、設計を行うための最前のアプローチには「複雑化」がある示唆しています。これはどう行った意味でしょうか？
A3. 最も簡潔な用語（概念レベル）によって問題を捉え、その後、追加機能を付加（区別）し、情報の追加によって設計をより複雑化していく考え方

Q4. Alexanderにとって、パターンは何の関係を定義するものなのでしょうか？
A4. 問題領域における実体化の関連を定義するもの

Q5. Alexanderの設計手順を述べてください。
A5. 
・パターンの洗い出し：問題領域内に存在するパターンを洗い出す。洗い出したパターンを用いて問題について考える。ただし、パターンの目的が実体間の関連を定義するものであることは忘れないようにする。
・コンテキストを作るパターンの発見：最初に、他のパターンのためのコンテキストを作るパターンを洗い出す。
・コンテキスト内への着目：それ以外のパターンと、発見していない他のパターンがないかという点に着目する。これらの作業で得られたものから、残りのパターンのためのコンテキストを作るパターンの洗い出しを行う。
・設計の洗練：パターンのが意味しているコンテキスト常に意識しながら行う。
・実装：詳細を組み込む。

## 応用
Q1. Alexanderは、「既存の部品を追加していくことによって自然なものを作ることは不可能である」と述べています。これはどう行った意味なのでしょうか。
A1. 単に既存のものを組み合わせるだけでは、特定のニーズにうまく合わせたものを作ることができず、ニーズにフィットさせて行くには、より大きな全体のコンテキストの中に位置付けが必要ということ。（抽象クラスによる、インターフェースなど）

# 第13章：CAD/CAMの問題をパターンによって解決す
## 基礎
Q1. この章で解説した、パターンを用いたソフトウェア設計の３つの手順を答えてください。
A1. 
・パターンの洗い出し
・パターンの分析・適用
・詳細の追加

Q2. コンテキストを定義してください。
A2. 何らかのものをその中に存在させる、または発生させる、互いに関連し合う条件、環境や設定のこと。

Q3. 最年長のパターンを定義してください
A3. システム内に存在し、他のパターンのためのコンテキストを構築する、１つまたは２つのパターン。これによって、他のパターンの行えることが限定される。

Q4. ２つのパターンのうち、どちらが「年長」であるかを調べるための２つの規則を答えてください。
A4.
・あるパターンが他のパターンの振る舞い方を定義しているか。
・２つのパターンが互いに影響を与えあっているか。

Q5. パターンの一般的構造を定義してください。それはいつ使用
するのでしょうか？
A5. 
クラス図のこと。問題に適用する際に、クラス名を置き換えるなどして使用する。


## 応用
Q1. パターンを用いれば、必ず問題を定義することができるのでしょうか？できない場合、他に何が必要なのでしょうか？
A1. 
できない。パターンを用いる方法は、問題領域全体をパターンの観点から理解出来る場合にのみ有効。一般的には、問題領域内に存在する概念間の関係を洗い出すことにより、他の部分を肉付けする必要がある。これは、共通性/可変性分析によって行う。

Q2. CAD/CAMの問題に置いて、Abstract Factoryは「最年長」のパターンから除外されました。その理由を答えてください。
A2. 
オブジェクトの使用によって生まれるパターンは、オブジェクトの実体化に関するパターン（生成に関するパターン）のためのコンテキストを生成する。よって、必要となるオブジェクトを決定したあとにファクトリが定義される。つまり、ファクトリはコンテキストを生成するパターンではないので、除外される。（よって、この問題に限らず、一般的にAbstract Factoryは最年長のパターンになりづらい）

Q3. CAD/CAMの問題に置いて、BridgeがAdapterよりも年長であると判断された理由は何でしょうか。
A3.
Adapterパターンは、インタフェースを変更するものである。この例では、OOGFeatureをクライアンの期待するインタフェースに変える。Bridgeパターンは、抽象的側面ｎにおｋる複数の具体例をその実装から切り出すものである。この例では、抽象的側面であるFeatureを実装V1,V2から切り離す。このとき、Bridgeパターンは、OOGFeatureを元々とは異なったインタフェースで使用する。そのため、Adapterを必要とする。よって、BridgeがAdapterを使用する。よって、BridgeパターンがAdapterパターンのコンテキストを生成するため、Bridgeがより年長と判断された。
Windows EC2 パスワードが分からなくなった場合

メモ
勉強用に適当やっていたらWindowsのadministratorのパスワードを忘れてしまった。また繰り返しそうなのでメモ。

スナップショット作成、
AMI登録、
新規EC2をこのAMIで生成、
このときに秘密鍵を新規作成、
インスタンス起動時にこの秘密鍵でadministrator password 取得


(*)調べたらその他system manager でもリストアできそうでした。
PC-98 MASM32でSSGサウンド

```sound.asm
comment *
        sound.asm for MASM32
ml /c /AT /Fl sound.asm
link16 /t sound;
*
        .model  tiny
        .code
;       org     100h            ; .com
        org     0h              ; IPL
start:
        push    cs
        pop     ds
        mov     ax, 0a000h
        mov     es, ax

        mov     al, 08h         ; 振幅 A
        mov     ah, 0
        call    wrtpsg
        mov     al, 01h         ; トーン・ジェネレータ A
        mov     ah, 01h         ; ftone=01deh 125,000/261.6Hz(C4)
        call    wrtpsg
        mov     al, 00h
        mov     ah, 0deh
        call    wrtpsg
        mov     al, 07h         ; ミキサー
        mov     ah, 0feh
        call    wrtpsg

        mov     bl, 0           ; note off
mloop:
        mov     ah, 04h         ; KSENS2
        mov     al, 05h         ; キーコードグループ番号
        int     18h             ; キーボードBIOS

        test    ah, 08h         ; Cキー
        jz      keyup
keydown:
        cmp     bl, 0
        jnz     disp            ; skip if note on
        mov     al, 08h
        mov     ah, 12
        call    wrtpsg
        mov     bl, 1           ; note on
        jmp     disp
keyup:
        cmp     bl, 0
        jz      disp            ; skip if note off
        mov     al, 08h
        mov     ah, 0
        call    wrtpsg
        mov     bl, 0           ; note off

disp:                           ; 表示
        mov     di, 0
        mov     cx, 8
@@:
        shl     ah, 1
        mov     al, 0
        adc     al, '0'
        mov     es:[di], al
        inc     di
        inc     di
        loop    @b

        jmp     mloop

; al=addr ah=data
wrtpsg:
        mov     dx, 188h        ; ライトアドレス
        out     dx, al
        mov     dx, 18ah        ; ライトデータ
        mov     al, ah
        out     dx, al
        ret

        end     start
```
vimのgitプラグインを作ってる話  

2018 08/29 機能追加分の追記
2018 09/11 機能追加分、修正、dein.vimの追記  

# TS;DR 
普段Vimを使っててたまーにターミナルに戻らずvimの中からGitコマンドを使いたいたい時があったので  
簡単にプラグインを作ってみた  
[Vitter](https://github.com/723gt/vitter)  

# コマンド  

現状使える基本的なコマンドは以下の通り   

### git branch
`:Gb <オプション>`    

### git checkout  
`:Gc <オプション>`  
`checkout`でファイルを開いてるファイルを直接した場合は一度閉じる  

### git log  
`:Gl <オプション>`  

### git diff  
`:Gd <オプション>`  

### git rebase  
`:Gr <オプション>`  

### git fetch  
`:Gf  <オプション>`

## その他コマンド  
### 現在開いてるファイルをcheckoutする  
`:Gcf`  

# その他機能  
vimのステータスライン上で現在のブランチを表示する  
vimのステータスラインが有効になっていない場合は`.vimrc`に以下を追記して有効化してください  

```vim

" ステータスラインの有効化
set laststatus=2 
" 以下を右寄せにする
set statusline+=%= 
```

次にステータスラインでブランチを表示させます 
上記のしたに以下を追記します  

~~`set statusline+=%{g:this_branch}`~~
2018/09/11 ステータスラインを有効化していれば自動で表示されるよにしました    

これでvimのステータスラインに現在のブランチが表示されます  
<img width="591" alt="スクリーンショット 2018-08-29 18.09.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/98200/564c0e69-01c7-4677-6092-275cd0793592.png">


# インストール  

pluginディレクトリの下にファイルを配置するとNeoBunlde,dein.vimで入れれる様になるため  
NeoBundle,dein.vimで簡単に入れれるようにした  

.vimrcのNeoBundleの設定内に以下を追記すれば次vimの起動時にインストールしてくれる  
**NeoBunldeの使い方は適当に調べてください**  

以下追記  
NeoBundle  
` NeoBundle "723gt/vitter"`  
dein.vim  
`call dein#add('723gt/vitter')`
# 今後  
まだまだ完全に使える状態じゃないので時間を見つけてアップデートしていきたい 
具体的には  
- `git rebase -i hoge`等をしたときエディタが起動しないため現状使えない
- 開いてるファイルが変更されたときに更新されない(現状強制的に閉じている)
- 実装していないgitコマンドがある(addとcommitは追加する気はあまりない)  

とりあえずこんな感じでゆるく作ってます  
日本語版README代わりにでもなれば  
バグや機能追加等あれば[ここに](https://github.com/723gt/vitter)issueかPRください
【超簡単】フロントエンドを Capistrano でデプロイする方法

# はじめに

Capistrano は万能です。Rails 以外でも使えます。
むしろ Rails 以外で使う方がなんやかんや導入しなくていいので簡単です。

というわけでフロントエンドを Capistrano でデプロイする手順を書いてみます。

# 前提

次のようにして作った foo-app という Vue.js のアプリがあるとします。

```bash
npm install -g vue-cli
vue init webpacker foo-app
cd foo-app

git init
git add -A
git commit "initial commit"
```

ここは React のアプリでも、静的なHTMLでもなんでもいいです。

# ここから本題で、まず Gemfile を作成

```bash
bundle init
```

# capistrano gem を追加

```bash
bundle add capistrano --group development
```

自動的に `bundle install` も走ります。

# capistrano の設定ファイルを生成

```
cap install
```

`config/deploy.rb` などができます。

# デプロイの共通設定を記述

```ruby:config/deploy.rb
lock "~> 3.11.0"
set :application, Pathname(__dir__).dirname.basename.to_s
set :repo_url, "file://#{Pathname(__dir__).dirname}"
set :deploy_to, "/var/www/#{fetch(:application)}-#{fetch(:stage)}"
```

`application` はアプリ名を指定します。このプロジェクトだと 'foo-app' です。`__dir__` を元に名前を決めると管理するものが減るのでオススメですが、余計にわかりにくいって場合は直接書いてもよいです。

`repo_url` は git のリポジトリを指定します。この例では localhost にデプロイ(設定は後述)するため repo_url を `file://` ではじまる url にしていますが外部にデプロイする場合は  github のリポジトリ URL などを指定します。

`deploy_to` はデプロイ先ホスト内のパスを指定します。

# production 用の設定を記述

```ruby:config/deploy/production.rb
server "localhost", user: "deploy", roles: ["web"]
```

この例だと localhost に deploy ユーザーで ssh ログインすることになります。

また `cap xxx deploy` を実行したときの `xxx` の部分が `config/deploy/xxx.rb` に対応して読み込まれます。

# デプロイ実行

```bash
cap production deploy
```

これだけです。

# デプロイのあとでビルドしたい場合は？

config/deploy.rb に以下を**追加**すると連動して `npm run build` が実行できます。

```ruby:config/deploy.rb
desc 'npm run build'
after 'deploy:updated', :build do
  on roles :all do
    within release_path do
      execute :npm, 'install'
      execute :npm, 'run', 'build'
    end
  end
end
```
Rancher 2.0 バージョンアップ

Rancher をバージョンアップしようとしていつもいつもデータを吹っ飛ばしてしまうので、ミスらないようにシェルスクリプトを書きましたとさ。

## 1. 前提
Rancher シングルインストールが前提(HAとかMultiの場合はドキュメント読んで)
コンテナーIDは自分で埋め込み。
そのうち自動で取得するようにしてもいいかも。
バージョンも埋め込み(適当に誰かいい具合にして)。

## 2. シェルスクリプト

Upgrades and Rollbacks | Rancher Labs
https://rancher.com/docs/rancher/v2.x/en/upgrades/
このドキュメントそのままだけど、それでも、まあ失敗する奴もいるってことさ。

```bash:rancher2-upgrade.sh
#!/bin/bash

export RANCHER_CONTAINER_ID=<>
export RANCHER_CURRENT_VERSION_TAG=v2.0.2
export UPCOMING_VERSION=v2.0.6

docker ps
docker stop $RANCHER_CONTAINER_ID

docker create --volumes-from $RANCHER_CONTAINER_ID \
--name rancher-data rancher/rancher:$RANCHER_CURRENT_VERSION_TAG

docker run  --volumes-from rancher-data -v $PWD:/backup \
alpine tar zcvf /backup/rancher-data-backup-$RANCHER_CURRENT_VERSION_TAG.tar.gz /var/lib/rancher

docker pull rancher/rancher:$UPCOMING_VERSION

docker run -d --volumes-from rancher-data --restart=unless-stopped \
-p 80:80 -p 443:443 rancher/rancher:$UPCOMING_VERSION
```

gistに貼ったので適当にご利用ください。
https://gist.github.com/ynott/5c53809549a254f675baa00372499e70

## 3. 使い方

### 3.1 RANCHER_CONTAINER_ID

docker ps してもいいし、
`sudo docker ps --filter ancestor=rancher/rancher --format "{{.ID}}"}`
とかしてもいいかもね。

### 3.2 RANCHER_CURRENT_VERSION_TAG

適当に入れてください。

### 3.3 UPCOMING_VERSION

exportのところを Docker Store から探して
rancher/rancher Tags - Docker Store
https://store.docker.com/community/images/rancher/rancher/tags

バージョン指定する

例：v2.0.7

### 3.4  実行

` $ bash ./rancher-upgrade.sh `
でよかろうかと
curlコマンドを使って、ストレージサービスにファイルをアップロードしたい

# はじめに
クラウドのストレージサービス（s3とかBlobとか）に、ファイル転送したいなって時がたまにあります。
しかも日付でディレクトリ分けられると、なお嬉しい的なこともしばしば。

既に同じようなスクリプトは多く出回っているのですとは思うのですが、
必要なだなぁーと思う時は、大体 忘れてしまっており、その都度調べて作るということが多々あったため、
個人用のテンプレート的なものを置いておこうと思いました。

# ということで、早速サンプルスクリプト
適宜、ファイル名やアクセスキーなどを変更したら使えるかと思います。

```bash:curl_upload.sh
#!/bin/bash

file="FILE_NAME"
bucket="BUCKET__NAME"
subdir=`date +%Y%m%d`

resource="/${bucket}/${subdir}/${file}"
contentType="text/plain"
date="$(LC_ALL=C date -u +"%a, %d %b %Y %X %z")"

accessKey="ACCESS_KEY"
secretKey="SECRET_KEY"

# s3の場合は、endpointは無くても良いかも（その時の環境に合わせて使用する）
endpoint="https://STORAGE_PROXY_ADDRESS"

stringToSign="PUT\n\n${contentType}\n${date}\n${resource}"
signature=`echo -en ${stringToSign} | openssl sha1 -hmac ${secretKey} -binary | base64`

curl -k -X PUT -T "${file}" \
  -H "Host: ${endpoint}" \
  -H "Date: ${date}" \
  -H "Content-Type: ${contentType}" \
  -H "Authorization: AWS ${accessKey}:${signature}" \
  https://${endpoint}/${bucket}/${subdir}/${file} -v
```

最近は、様々なストレージサービスがあるので、うまいこと利用できれば幸いです。
VMware Fusionのディスクサイズを大きくする

VMware Fusionのディスクサイズを大きくするには、下のステップが必要です。
1.はGUIから簡単に実行できるので省略します。

1. VMware Fusionの仮想ディスクのサイズを拡大
2. その後、パーティションのサイズを変更

### ボリューム名を取得
```
diskutil list
```
### 特定したボリュームを対象にして、サイズを変更
```
diskutil resizeVolume <Name> R
```
Chromeを使って、画像ファイルをA4サイズでPDFにした

# 概要
ZIP本をPDFに変換するお話です。

GoogleDriveで、ZIP本を見るのが面倒なので変換しました。

# 環境
- Chrome
- windows

# 手順
1.htmlファイルの作成
2.chromeで開く
3.印刷 ( PDF ) 

# コード

下のコードをindex.htmlで保存し、ブラウザで開いて(ドラッグするだけ)、印刷(CTRL-P)するだけです。

- jpgファイルは、環境に合わせて増やします。
- プレビュー風に表示しています。
- ページ番号を表示しています。

```:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0px;
padding: 0px;
}
img {
max-width: 100%;
max-height: 100%;
}
.a4 {
width: 210mm;
height: 297mm;
/* border: 1px solid #333; */
page-break-after: always;
display: block;
overflow: hidden;
}
@page {
margin: 0mm;
}
@media  screen {
html, body {
width: 100%;
}
body {
background: #eee;
counter-reset: sheet;
}
.a4 {
background: white;
box-shadow: 0 .5mm .2mm rgba(0,0,0.3);
margin: 5mm;
display: inline-block;
position: relative;
}
.a4:after {
counter-increment: sheet;
content: counter(sheet);
position: absolute;
padding: .5mm;
background: #fff;
top: 0px;
left: 0px;

}
}

</style>
</head>
<body>
<div class="a4"><img src="001.jpg"></div>
<div class="a4"><img src="002.jpg"></div>
<div class="a4"><img src="003.jpg"></div>
<div class="a4"><img src="004.jpg"></div>
</body>
</html>
```
Atomエディタを完全にアンインストールする(Mac)

# 概要
MacのAtomエディタ(以下、Atom)を利用しているのですが、最近になってAtomの挙動がおかしくなり、メニューバーから各種メニューが開けなくなったり、ファイルを開く際のドラック&ドロップが利用不能になったりしました。。。そのため、原因調査せず、Atomを完全にアンインストールして、再度インストールすることにしました。

# Atomを完全にアンインストールする場合、関連ファイルも削除する必要がある
単純にアプリアイコンをゴミ箱に入れるなどしてAtom.appを削除するだけでは、Atomの関連ファイルを削除することはできないようです。私の場合、関連ファイルを削除しないまま再インストールしても、挙動はおかしいままでした。

# Atomの関連ファイルを削除する

```terminal
rm -rf ~/.atom
rm -rf /usr/local/bin/atom
rm -rf /usr/local/bin/apm
rm -rf /Applications/Atom.app
rm -rf ~/Library/Preferences/com.github.atom.plist
rm -rf ~/Library/Application\ Support/com.github.atom.ShipIt
rm -rf ~/Library/Application\ Support/Atom
rm -rf ~/Library/Saved\ Application\ State/com.github.atom.savedState
rm -rf ~/Library/Caches/com.github.atom
rm -rf ~/Library/Caches/com.github.atom.Shipit
rm -rf ~/Library/Caches/Atom
```

# まとめ
Atomを完全にアンインストール(関連ファイルも削除)してから再インストールを行うことで、挙動の問題は解消されました。今後のために、備忘録として残しておきます。

# 参考
[How to Completely Uninstall Atom for Mac?](https://discuss.atom.io/t/how-to-completely-uninstall-atom-for-mac/9084)
[【Mac】Atomエディタの挙動が変でアンインストールしたら動いた](https://blog.stedplay.com/how-to-uninstall-atom-in-mac/)
[【Mac】Atomエディタを完全にアンインストールする](https://qiita.com/tor_2085/items/a7d7317d4d41bc8127be)
grepでパターンにマッチした文字列だけを出力する（-o オプション）

たまにしか使わなくてよく忘れるのでメモ。

実際にはこんなシチュエーションだった。

postfixのメールログからステータスの統計とろうとしていた。
しかし、postfixのログフォーマット的に、`status=xxx` の現れる位置が
スペース区切りで考えてもカンマ区切りで考えても一定にならないので
`cut` や `awk` では切り出せなくて[^1]
[^1]: `awk` にあまり詳しくないので何かやり方あるのかもしれないが当時は思いつかなかった。
なんか方法ないかな・・・と調べていて
`grep`の `-o` オプションでできることに気づいた。

```shell-session
$ grep -E -o ”status=\S+” /var/log/maillog | sort | uniq -c
   1386 status=bounced
  40125 status=deferred
    167 status=expired,
   7197 status=sent
```
めっちゃエラー出てた:sweat_smile:
（このエラーはその後無事に解消した）
GoogleCloudのGAEを使ったWebAPI作成方法

現在(2018/08/13)Googleで12か月無料のサーバを使えると聞いたので、それを使うためのメモ。

##まずは登録
参考:[ゼロから始める Google App Engine の使い方](https://blog.apar.jp/web/6912/)

Google Cloudでは、無料トライアル登録の際にクレジットカードの番号入力を求められるがこれは個人特定のために必要なものらしい。
今のところ何の請求も来てないので多分大丈夫なのだろう。

上記のリンク先記事は一年前のものになるが使い方は変わっておらずそのままの手順で登録・使用開始することができた。

##環境設定
Google Cloud SDKをインストールが完了するとshell画面入力でログインやアップロードができるようになる。
使いたいフォルダをshift+右クリックするだけでPowershellをそのフォルダで開けるのでそれを使うとちょっと楽
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280621/93e65927-ca03-e351-19d0-3beef86f77c9.png)

またXAMPPなどのlocal環境が作れるソフトとAtomなどのテキストエディタを用意しておくと開発がしやすかった。

##コマンド
基本的に使うコマンドは二つ
gcloud init　と　gcloud app deploy
initでログインして、deployでアップロードするだけでサーバにデータを送信できる。
一応ページを確認したければ、gcloud app browseのコマンドで確認できるが別に使わなくてもいい

##PHP
###echo,変数
PHPにはC言語と違い変数型宣言が不要で変数名を$から始めることで区別している
「''」で文字列を定義し、「.」で文字列結合ができる。便利
表示するときはechoと使えばHTML表示される

```php
$TEXT = 'TEST TEXT';
echo '入力テキストは' . $TEXT . 'です。';
```

```
実行結果:
入力テキストはTEST TEXTです。
```

###GET,POST
HTMLのURLから情報を取得するには_GETを使えばその名前の値を拾うことができる
逆に送りたいときは_POSTを使えば情報添付して送信できる。
[PHPでフォームからデータを受け取る方法](https://techacademy.jp/magazine/4955)

```php
$Input = $_GET['in'];  
$Output= $_POST['out'];
```

###保存先
Google Cloudで厄介なところとして、localとデータの保存されるところが違う
本来なら

```php
$Fulename = 'test.txt';
file_get_contents('./' .$FileName);
```

これでtest.txtを開くことができるのだが、Google Cloudだと

```php
$Fulename = 'test.txt';
file_get_contents('gs://xxxxxxxxxx.appspot.com/' .$FileName);
```

になる(xxxxxxxxxxはプロジェクト名)
localとGoogle Cloudを手動で変える必要があるので、注意する必要がある。

```php
define("FILE","./");
```

で定義しておけるので適時コメント化すれば少し楽になると思う。

##yamlって何よ
>app.yaml の作成
Google App Engine にデプロイするには「app.yaml」という設定ファイルが必要になります。
設定ファイルは、YMAL（ヤムル）というフォーマットで記述します。

とのこと
正直使ったことがないので全く意味が分からなかったが要するに
HTMLとしてサーバを使うときに「どの言語で記述されている」かと「どこにアクセスするとどの機能が動くか」が書いてあるようだった

```
- url: /.*
  script: xxx.php
```

これでプロジェクトのどこにアクセスしてもxxx.phpが起動することになる。

```
- url: /a
  script: a.php

- url: /.*
  script: xxx.php

- url: /b
  script: b.php
```

このように２つ以上書く時には上から順に割り当てられていきa.phpにはアクセスできるがb.phpにはアクセスできなくなる(xxx.phpにつながってしまう)ので注意が必要
他にもいろいろ機能があるようだが詳細は[Google Cloud Configuration Files](https://cloud.google.com/appengine/docs/standard/php/configuration-files)に書いてある

##おわりに
PHPにGETやPOSTを送ってDBにアクセスするサーバサイトを作りたくて適当に調べたもののまとめ
英語が読めればもっと詳しく書いてあるものもたくさんあったんだろうけども英語ばっかりなのがつらたんです(´・ω・｀)
Google Cloudの無償期間を過ぎた後も個人利用程度なら無料で使えるようなので、これを使って遊んでいきたいなーと思ってます。