(6歩目)

###昨日の振り返り、学び

###今日の思い
心なかで大きな声を出す
政府から逃げるのは本当に疲れる

自分の思いをまっすぐもつ

自分が自分の先生である
マスターの姿を知っている
でも自分は最上のマスターではない
走りかけのマスターだ

###今日の目標、計画

##今日やること
リモートの仕事
海外駐在の仕事探し
骨董品屋連絡

スーパー
マザーズ


**求職活動**
 - indeed
 - linkedin
 - jobstreet


**人間関係**
- 渡辺さん

**検索**
- 金剛鈴

**意味のないこと**
ピアノ
体の本

### スケジュール
- 7:00
- 9:00
- 12:00
- 15:00
- 18:00
    
----

**資産関連**

**今日の日記**

今日も訳がわからないままに一日が過ぎた
職探しをしなければならない、という焦りとそれをせずに時間が経っていく。

自分は何がしたいのか。
どこにその答えがあるのか。
わからないなまま、今日も終わった

終わりはあやの話を聞きながら眠りにつくという始末。


**明日やること**

**待ち案件**
leaflog 岡田さん
global platform 河上さん

学習記録 (3/2 -3/19 )

Minitest

if $0 == __FILE__
  Sample.new(ARGV[0],ARGV[1],ARGV[2]).run
end

を実行のロジックに入れることで別のパスで実行するとき(特にテストコード)のエラーを防ぐ

ARGVは定数なのでコード内のどこでも呼び出せる

テストコード

assertequalで検証されるのはメソッドの戻り値(標準出力ではない) テストしやすくするためにコードを戻り値ベースでかき、最終的に出力する形が理想に思える。

  • cat -は入力をそのまま出力する
  • readlinesは改行しても入力が終わらない、Ctrl+Dで入力が終了する。
  • File.pipe?(STDIN) パイプによる標準入力の有無の判定
  • STDIN$stdinに書き換えることができる。
  • 戻り値が複数ある場合はreturnに戻り値をカンマ区切りで表示。メソッドから複数の要素に代入する。
def wc_files(files, option)
  output_files = ''
  total = { 'lines' => 0, 'words' => 0, 'bytes' => 0 }
  files.each do |filepath|
    str = File.read(filepath)
    lines = str.count("\n")
    words = str.split(/\s+/).size
    bytes = File.stat(filepath).size
    output_files += lines.to_s.rjust(8)
    output_files += option['l'] ? " #{filepath}\n" : "#{words.to_s.rjust(8)}#{bytes.to_s.rjust(8)} #{filepath}\n"
    total['lines'] += lines
    total['words'] += words
    total['bytes'] += bytes
    end
    return output_files, total
  end

return output_files, total[return output_files, total]と記述することができる

この戻り値を複数の変数に代入する。

    output_files, total = wc_files(files, option)
    output += output_files

filepahオブジェクト

ディレクトリであってもファイルであってもパスとして扱う Pathname.getwd : オリジナルのファイル(実行しているファイルではなく)のカレントディレクトリのパスを取得、require 'pathname'が必要 Pathname.new(文字列) : 文字列をもとにpathnameオブジェクトを作る/ Pathname()と同値 - File.extend_path:相対パス絶対パスに変換 File.extend_path("..") = 親ディレクトリまでの絶対パス

p Dir.getwd                      #=> "/home/matz/work/foo"
p ENV["HOME"]                    #=> "/home/matz"
p File.expand_path("..")         #=> "/home/matz/work"
p File.expand_path("..", "/tmp") #=> "/"
p File.expand_path("~")          #=> "/home/matz"
p File.expand_path("~foo")       #=> "/home/foo"
  • File.dirname : filenameのいちばん後ろのスラッシュより前を文字列として返す
p File.dirname("dir/file.ext")    # => "dir"
p File.dirname("file.ext")        # => "."
  • ヒアドキュメント 基本は ``` <<TEXT . . .

    TEXT

<<~にするとヒアドキュメント内の全行の頭のインデントが無視される

ヒアドキュメントの中では\や式展開が有効 識別子TEXTは自由。''で囲むとシングルクオート、""で囲むとダブルクオート

  • ヒアドキュメントに<<~TEXT.chompのようにメソッドを追加することができる。

  • バッククオートで囲むと``ターミナル実行結果が返る

path = "/Users/takunaka"
p expected = `ls #{path}`

#=> 
"Applications\nCalibre Library\nDesktop\nDocuments\nDownloads\nFBC\nGemfile\nGemfile.lock\nLibrary\nMovies\nMusic\nPictures\nPublic\nTEST\nTEST2\nVirtualBox VMs\nWine Files\nbin\necho\ngittutorial\nhello-world\nhotger\npatchwork\nresult\nrubybook\ntutor\nwork\n"

コミットの取り消し : git reset --soft HEAD^ ステージングの取り消し : git reset HEAD

  • getsコマンドは改行の"\n"まで含まれる、文字列だけを取り出すためにはchompメソッドを使用する。readlineも同様(readlinesは複数行を一度に読み込む別メソッド)だが読み込めない行があるとreadはEOErrorを返し,getsはnilを返す
  • ファイルの読み込み : str = File.read("./test_file.rb")
  • readは文字列、readlineは配列として取得
  • readlines gets readlineは標準入力を要求する。要求する入力方法は、

    • コマンドの引数のファイル名(ファイルをopenする)
    • パイプライン
    • 引数とパイプラインがある場合は引数が優先される(メソッドが標準入力を選択している)
    • 複数の引数がある場合でも一つ目の引数しか読み込まない
    • readline/readlines/getsは変数ではなく入力。読み込まれていったら順次消えていく。一度変数に代入したら次の変数には代入されない。
  • require 'optparse''を入れなければオプション-lはARGV配列に含まれるがoption = ARGV.getopts('-l')メソッドを入れることにより、-l`はA{"l" => true}という新たなハッシュに代入されARGVから除外される。

byebug

  • byebug (ファイル名で実行)/ rubyコマンドに-rbyebygオプションをつける / require 'byebug' ; byebygをファイルにrequireする。
  • c/s/fin/restart/next(メソッドの中に入らない)

*SQL入門 - データを集めることの大切さ - データの基準 <完全性><正確性><妥当性><一貫性><適時性> タイミングがふさわしく。正しい前提に基づき、矛盾なく、正確で漏れのないデータ「データに偏りがなく正確で新しいデータ」 - 不特定多数ののユーザーが同時に利用するデータベースの整合性を担うのがDBMS - DBMSはデータに対するアクセス要求に応えるソフトウェア - データベースの種類 - リレーショナル/RDB : 二次元表現、人が理解しやすい - オブジェクト指向データベス/OODB : オブジェクトを保存する - XMLデータベース/XMLDB : XML形式のデータを扱う - 階層型データベース : データを階層構造で表現する - ネットワーク型データベース : 階層構造だが横つながりも持つ

  • DBMSの種類 商用

  • OSSDBMS

  • 3層スキーマ

    • 外部スキーマ(ビュー)/概念スキーマ(テーブル定義)/内部スキーマ(データの物理配置)
    • スキーマを分けることで変更がほかのスキーマに影響を与えない
    • 概念スキーマを考える論理設計、データモデルをつくる ERモデル entiti(実態)reltionship(関連)attirbute(属性)を図で表したもの
  • データベースの物理設計

    • テーブル定義
    • インデックス定義
    • ハードウェアのサイジング
    • ストレージの冗長構成決定
    • ファイルの物理配置決定
  • RAID 高い耐障害性を持つシステム Redundant Array of Inexpensive Disks データを複数のディスクに分散

  • RAIDのレベル

    • 0 : 高速化と大容量化(ストライピング)
    • 1;耐障害性に特化した単純構成(ミラーリング)
    • 5:高速、大容量、冗長(分散型)、パリティ(誤り訂正符号)分散
    • 10:ミラーリング x ストライピング 冗長化とは複数のディスクに同じデータを書き込むこと
  • データベースのI/Oスピードがデータベースの性能問題の元凶

  • PostgreSQL

    • オンラインバックアップ/ストアドプロシージャ
    • レプリケーション : 複数のサーバにデータベースを自動的に複製する機能

SQLの分類 - DDL(Data Definition Language) DDL(データ定義言語)は、テーブルなどのオブジェクトを作成するためのコマンド群です。DDLに分類されるコマンドは以下になります。

  • CREATE データベースやテーブルなどを作成する。
  • DROP データベースやテーブルなどを削除する。
  • ALTER データベースやテーブルなどの構成を変更する。

  • DML(Data Manipulation Language) DML(データ操作言語)は、データの挿入/更新/削除などを行うためのコマンド群です。DMLに分類されるコマンドは以下になります。

    • SELECT テーブルから行を検索する。
    • INSERT テーブルに新規行を登録する。
    • UPDATE テーブルの行を更新する。
    • DELETE テーブルの行を削除する。
  • DCL(Data Control Language) DCL(データ制御言語)は、トランザクション関連のコマンドが含まれます。DCLに分類されるコマンドは以下になります。

    • COMMIT データベースに対して行った変更を確定する。
    • ROLLBACK データベースに対して行った変更を取り消す。
    • GRANT ユーザーに操作の権限を与える。
    • REVOKE ユーザーから操作の権限を奪う。
  • SQL記述ルール

    • 文末にセミコロンをつける
    • 大文字小文字は分けない
    • 定数はシングルクオーテーションで囲む
    • 数値はそのまま記述
  • psql SQLインタプリタ

  • シェルからpsqlコマンドを実行
    • psql -U <データベースユーザー名> <データベース名>
    • -l データベース一覧を表示する。コマンド実行後、データベースに接続したままにならず、プロンプトに戻る。
    • c ‘コマンド’ 引数で指定したSQLコマンドを実行し、結果を表示する。コマンド実行後、データベースに接続したままにならず、プロンプトに戻る。 -f ファイル名 引数で指定したファイルの中身をSQLとして実行する。コマンド実行後、データベースに接続したままにならず、プロンプトに戻る。
    • p ポート番号 接続するPostgreSQLのポート番号を指定する。
    • h ホスト名 接続するPostgreSQLのホスト名を指定する。

バックスラッシュコマンド 説明 \? バックスラッシュコマンドヘルプを表示 \h SQLヘルプを表示 \q psqlを終了 \l データベースの一覧を表示 \dn スキーマの一覧を表示 \d テーブル、インデックス、シーケンス、ビューの一覧を表示 \dt テーブルの一覧を表示 \di インデックスの一覧を表示 \ds シーケンスの一覧を表示 \dv ビューの一覧を表示 \dS システムテーブルの一覧を表示 \du データベースユーザーの一覧を表示 \df 関数の一覧を表示 \r 入力途中のクエリのリセット \timing SQL実行時間計測表示のON/OFF

  • CREATE TABLE

    列に指定する制約として以下の項目があります。

PRIMARY KEY 主キーとする。 UNIQUE 列内で重複する値を許可しない。 REFERENCES 表名(列名) 外部キーとする。参照先は指定した表名(列名)となる。 CHECK(条件) 条件に合う値のみ登録を許可する。 NOT NULL NULL値(空の値)を許可しない。 DEFAULT 値 新規行追加時の初期値を指定する。

  • INSERT INSERT INTO テーブル名 [(列名1 [, 列名2 …] )] VALUES (値1 [, 値2 …] );

    testdb=# INSERT INTO Staff (id, name, age) VALUES ('0001', '山田太郎', 26); testdb=# INSERT INTO Staff (id, name, age) VALUES ('0002', '佐藤隆', 34); testdb=# INSERT INTO Staff (id, name, age) VALUES ('0003', '斉藤達弘', 45);

testdb=# INSERT INTO Staff VALUES ('0004', '渡辺さつき', 28);

  • SELECT SELECT 列名, … FROM テーブル名;

    testdb=# SELECT name FROM Staff; name


山田太郎 佐藤隆 斉藤達弘 渡辺さつき (4 行)

testdb=# SELECT * FROM Staff; id | name | age ------+------------+----- 0001 | 山田太郎 | 26 0002 | 佐藤隆 | 34 0003 | 斉藤達弘 | 45 0004 | 渡辺さつき | 28 (4 行)

-UPDATE 既存のデータの変更 UPDATE テーブル名 SET 列名 = 式 WHERE 条件式;

testdb=# UPDATE Staff SET name = '桜井さつき' WHERE id='0004';

  • 全行更新testdb=# UPDATE Staff SET age = 46;

    testdb=# SELECT * FROM Staff; id | name | age ------+------------+----- 0001 | 山田太郎 | 46 0002 | 佐藤隆 | 46 0003 | 斉藤達弘 | 46 0004 | 桜井さつき | 46 (4 行)

  • DELETE DELETE FROM テーブル名 WHERE 条件式; DELETEコマンドで削除するのは行(レコード)単位です。例えば、一部の列だけを削除すると言ったことはできません。

testdb=# DELETE FROM Staff WHERE id='0002'; testdb=# SELECT * FROM Staff; id | name | age ------+------------+----- 0001 | 山田太郎 | 46 0003 | 斉藤達弘 | 46 0004 | 桜井さつき | 46

testdb=# DELETE FROM Staff; testdb=# SELECT * FROM Staff; id | name | age ----+------+----- (0 行)

  • DROP TABLE DROP TABLE テーブル名;

    testdb=# \d リレーションの一覧 スキーマ | 名前 | 型 | 所有者 ----------+-------------+----------+---------- public | staff | テーブル | postgres public | testTable01 | テーブル | postgres (2 行) testdb=# DROP TABLE staff; testdb=# \d リレーションの一覧 スキーマ | 名前 | 型 | 所有者 ----------+-------------+----------+---------- public | testTable01 | テーブル | postgres (1 行)

【第1回】データベースとデータベース管理システム 1.1 データベース管理システムが扱うデータ

1.2 データーベース管理システムとアプリケーション アプリケーションは用途がある、DBMSはそれを汎用的に管理する

1.3 データベース管理システムはデータベースを守る DBMSはデータの出し入れと同時にバックアップや変更履歴を保存し故障時の復旧に備えている 1.4 データベースを使うと何人もの人が同時にデータベースを使える

【第2回】PostgreSQL って何? 2.1 PostgreSQL はフリーなオープンソースソフトウェア PostgreSQLソースコードは80万行 2.2 世界中の開発者が作る高品質なプログラム

2.3 長期間にわたる維持管理 維持管理:脆弱性や不具合のアップデート

2.4 業務システムに耐える品質・機能と性能

【第3回】リレーショナルデータベースと DBMS 超入門 3.1 リレーショナルデータベースとは「表」のこと? "表=テーブル=リレーション" フィールドは連結、分割ができない フィールドの値の同じ2つの行は区別されない 読み書きはSQLという言語を使って行われる 3.2 データベース管理システムは大量のデータを保持できる DBMSは変更と保存を同時に行う

3.3 データベース管理システムはデータを安全確実に保存する ログを使ってデータベースを最新の状態に戻すクラッシュリカバリ バックアップディスクとログを使ってデータベースを復元するアーカイブリカバリ

3.4 データベース管理システムは処理を中途半端で終わらせない トランザクションの途中で止まった処理は元に戻る DBMSトランザクションの単位を認識できないので、アプリケーションがそれDBMSに通知する必要がある。

3.5 データベース管理システムは同時に複数のアプリケーションからの読み書きをサポート

  • POSTGRE SQL ユーザーの追加・削除など基本の操作を覚える。 起動 /etc/init.d/postgresql start サーバを起動させpostgresユーザにアクセス、postgresはサーバのrootユーザ
su - postgres
psql -l

テンプレートデータベースが表示される

                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(3 rows)

postgres ユーザにアクセス

$ psql postgres

このコマンドは $ psql -U postgres postgresの省略版

\dでデータベースの中を参照

サンプルテーブルの作成

postgres=# CREATE TABLE sampletable
postgres-# (
postgres(# idnumber serial,
postgres(# name text
postgres(# )
postgres-# ;

\d テーブル名でテーブルの中身(定義された項目と属性)を確認

データの確認

select * from sampletable

データベースの停止、終了 exitpsqlユーザからログアウト、再びexitでデータベースよりログアウトした上で

/etc/init.d/postgresql stop

psqlでユーザとしてデータベースにアクセス

  • ユーザを追加 (LOGIN,PASSWORD,CREATEDB権限付き)
postgres=# CREATE USER "caminopsql" CREATEDB PASSWORD 'caminopsql' LOGIN;
postgres=# CREATE USER "caminosql" CREATEDB PASSWORD 'caminosql' LOGIN;

全ての権限を持ったroleを追加

CREATE ROLE user01。この時点ではなんの権限も与えられていない
                               List of roles

Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- caminosql | Create DB | {} postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} user01 | Cannot login ```

  • ユーザを削除
postgres=# DROP ROLE caminopsql;

\du作成済みのロールを表示 \du作成済みのデータベースを表示

postgres=# \du
                                    List of roles
 Role name  |                         Attributes                         | Member of 
------------+------------------------------------------------------------+-----------
 caminopsql | Create DB                                                  | {}
 caminosql  | Create DB                                                  | {}
 postgres   | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

SQLコマンドを実行するには最初にコマンドプロンプトを起動して psql を使って PostgreSQL に接続。 コマンドの入力途中ではプロンプトが=から-に変わる

postgres=# create table postgres-#

  • psql: error: FATAL: Peer authentication failed for user エラー

    peer認証とはPostgresのデフォルトの認証方法で、OS側のユーザー名とPostgreSQL側のユーザー名が一致していないと発生するエラーです。 デフォルトの状態であれば、以下の通りだとPeer認証のエラーが発生せずPostgresへログインすることが可能です。

/etc/postgresql/9.6/main/pg_hba.confこのサイトに則って変更

その後はコマンドラインから

psql -U user01 postgres

あるいは

psql -U user01 -d postgres

のような形でアクセスできる

だけれど、この場合スーパーユーザがアクセスできない(パスワードが未設定のため)

  • スーパーユーザのパスワードを設定

osでの設定 ソース 

# passwd postgres (nuttahに設定)
ユーザー postgres のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:

psqlにログインし、スーパーユーザのパスワード'postgress'を設定

postgres=# ALTER ROLE postgres WITH PASSWORD 'postgres';

コマンドからpsql -U postgrespsql -lのパスワード認証が通らなくなったので /etc/postgresql/9.6/main/pg_hba.confをさらに以下のように変更

# ↓追加

local all all trust

とすると

psql: error: FATAL:  role "root" does not exist

であるが, su - postgresでログイン可能

以下のコマンドでデータベース内でユーザに権限を追加削除できる

postgres=# GRANT SELECT ON sampletable ON user01;
postgres=# REVOKE SELECT ON sampletable FROM user01;

psql データベース名でデータベースにアクセス

学習記録 (2/25 -3/1 )

NGINXプラクティス等 (2/25 -3/1)

nginx

  • サーバ兼リバースプロキシのソフトウェア
  • VirtualBoxDebianにインストール
  • 静的なコンテンツを提供するwebサーバで、Webアプリケーションとの連携で動的コンテンツの提供が可能
  • リバースプロキシ (キャッシュサーバ)として利用可能
    • SSLアクセラレータ、ロードバランサとしての機能
    • Webアプリをnginxが直接動かすことはできない


  • 基本コマンド
# 起動
sudo /etc/init.d/nginx start
# 終了
sudo /etc/init.d/nginx stop
  • ローカルホストに接続できない...
taku-no-MacBook-Pro:~ takunaka$ telnet localhost 80
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying fe80::1...
telnet: connect to address fe80::1: Connection refused
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host
taku-no-MacBook-Pro:~ takunaka$ 
  • デフォルトのapacheではターミナルのsudo apachectl startから URLlocalhostでアクセスできた。 sudo apachectl stopで停止。

  • 接続可能。。。というかnginxを起動しているのはローカルホストではなく、virtualbox上のリモートホスト


  • nginx主なファイル構成
/etc/init.d/nginx

nginx の実行ファイル

管理者権限で末尾にオプションを指定して起動・終了等を行う
※ デーモンとしてOS起動時に自動で立ち上がるみたい

/etc/nginx/nginx.conf

全てのバーチャルホストに対する設定

Webサーバー全体に対して一括で変更を加えたい場合はこちらを編集する

/etc/nginx/sites-available/

全てのバーチャルホスト毎の個別設定ファイルを配置する
/etc/nginx/sites-enabled/

/etc/nginx/sites-available/に配置した設定ファイルのシンボリックリンクを配置する


  • nginx.confファイル
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}


#mail {
#   # See sample authentication script at:
#   # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#   # auth_http localhost/auth.php;
#   # pop3_capabilities "TOP" "USER";
#   # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#   server {
#       listen     localhost:110;
#       protocol   pop3;
#       proxy      on;
#   }
#
#   server {
#       listen     localhost:143;
#       protocol   imap;
#       proxy      on;
#   }
#}
  • /etc/nginx/sites-enabled/default
caminotak@debian:/etc/nginx/sites-enabled$ less default

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#       #
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#       # Note: You should disable gzip for SSL traffic.
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#       # See: https://bugs.debian.org/765782
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;

        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        # pass PHP scripts to FastCGI server
        #
        #location ~ \.php$ {
        #       include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
        #       fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
}


# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
#       listen 80;
#       listen [::]:80;
#
#       server_name example.com;
#
#       root /var/www/example.com;
#       index index.html;
#
#       location / {
#               try_files $uri $uri/ =404;
#       }
#}
        }


仮装サーバの構築

serverを復数記述することで、仮想サーバとして動作する http内に記述できるディレクティブは、だいたいserver内にも記述できる様子

http{
    server{
        server_name alpha.example.com;
    }
    server{
        server_name bravo.example.com;
    }
}

IPベース listenで別個のIPを指定することで、IPベースの仮想サーバを構築できる

http{
    server{
        listen 192.168.0.1:80;
        server_name alpha.example.com;
    }
    server{
        listen 192.168.0.2:80;
        server_name bravo.example.com;
    }
}
  • SSL(https)に対応する
    • listenで443ポートとSSLを使うことを指定
    • sslSSLを有効に
    • ssl_certificateで証明書+中間証明書のファイルを指定
    • ssl_certificate_keyで秘密鍵を指定
http{
    listen 443 ssl;
    ssl on;
    ssl_certificate      /path/to/cert.pem;
    ssl_certificate_key  /path/to/cert.key;  
}
  • MIMEタイプ: webサーバとwebブラウザの間で用いるデータ形式 [タイプ名/サブタイプ名]形式の文字列。メールヘッダやHTTPレスポンスヘッダなどに付与される
テキスト .txt    text/plain
HTML文書  .htm .html  text/html
XML文書   .xml    text/xml
JavaScript  .js text/javascript
VBScript    .vbs    text/vbscript
CSS .css    text/css
GIF画像   .gif    image/gif
JPEG画像  .jpg .jpeg  image/jpeg
PNG画像   .png    image/png
CGIスクリプト  .cgi    application/x-httpd-cgi
Word文書  .doc    application/msword
PDF文書   .pdf    application/pdf


VirutualHost

一つのサーバの中で複数のドメインを運用するための技術 サーバの設定の中に、ドメインごとに見せるサイトを切り替える設定をする。 サイト管理者のメールアドレスやエラーログ、アクセスログの設定も可能 ポート443のVirtualHost設定を追加して SSL証明書関連の設定を指定することでhttpsでのアクセスにも対応可能

  • home/demo/public_htmlの下で複数のバーチャルホストをフォルダ(フォルダ名'domain1.com'等)に分け管理

  • /etc/nginx/sites-available の下にバーチャルホスト(ドメイン)の設定ファイルを設置

サーバ名など:(例では'www.domain1.com''domain1.com'のふたつの名前を定めている。またロケーションも定められいる。listenはポートを示している。

server {
           listen   80;
           server_name www.domain1.com;
           access_log /home/demo/public_html/domain1.com/log/access.log;
           error_log /home/demo/public_html/domain1.com/log/error.log;
           location / {
                       root   /home/demo/public_html/domain1.com/public/;
                       index  index.html index.php;
                       }
           }
  • sites-enabledにシンボリックリンクを作成する(サイトが参照可能になる)
  • nginxの起動ポートの変更: etc/nginx/sites-enabled/defaultのポート番号を変更する
  • sites-enabled domain1.comのポートを8888にするとnginxは起動せず、88だと起動する。
  • nginxは、起動時に、ディレクトリ/etc/nginx/sites-enabledに入っている設定ファイルを読み込みます。
  • ここから先に出てくるNginxの設定ファイル内の「server」や「listen」、「location」などの項目を「ディレクティブ」といいます。

  • Nginxの設定ファイルはデフォルトで2つ、以下の順番で読み込まれます。

    • /etc/nginx/nginx.conf
    • /etc/nginx/conf.d/default.conf

そのほかにもconf.ファイルで以下のファイルが読み込まれている。

  • include /etc/nginx/modules-enabled/*.conf;
  • include /etc/nginx/mime.types;
  • include /etc/nginx/sites-enabled/*;

ドキュメントルートやHTMLファイルについては、「/etc/nginx/conf.d/default.conf」を開くことで確認できます。

と書いてあるが、/etc/nginx/conf.d/というディレクトリの中には何もない。。。

  • etc/nginx/の構成
drwxr-xr-x 2 root root 4096 May 29  2021 conf.d
-rw-r--r-- 1 root root 1125 May 29  2021 fastcgi.conf
-rw-r--r-- 1 root root 1055 May 29  2021 fastcgi_params
-rw-r--r-- 1 root root 2837 May 29  2021 koi-utf
-rw-r--r-- 1 root root 2223 May 29  2021 koi-win
-rw-r--r-- 1 root root 3957 May 29  2021 mime.types
drwxr-xr-x 2 root root 4096 May 29  2021 modules-available
drwxr-xr-x 2 root root 4096 Feb 25 22:02 modules-enabled
-rw-r--r-- 1 root root 1447 May 29  2021 nginx.conf
-rw-r--r-- 1 root root  180 May 29  2021 proxy_params
-rw-r--r-- 1 root root  636 May 29  2021 scgi_params
drwxr-xr-x 2 root root 4096 Feb 26 21:28 sites-available
drwxr-xr-x 2 root root 4096 Feb 26 21:08 sites-enabled
drwxr-xr-x 2 root root 4096 Feb 25 22:02 snippets
-rw-r--r-- 1 root root  664 May 29  2021 uwsgi_params
-rw-r--r-- 1 root root 3071 May 29  2021 win-utf

また、仮想ホストwww.foo.comを(一時的に)無効にするには、ステップ2で作成したシンボリックリックを削除して、Nginxをリスタートしてやります。 つまり、シンボリックリンクを作成すれば仮想ホストは有効になり、シンボリックリンクを削除すれば、仮想ホストは無効になります。 余談ですが、Ubuntuでは、apacheでも、2つのディレクトリsites-availableとsites-enabledを使って、仮想ホストを管理します。さらに、apacheでは、コマンドa2ensite(仮想ホストを有効する)とa2dissite(仮想ホストを無効にする)が用意されています。 しかし、Nginxでは、このようなコマンドは用意されていないので、手作業でsites-enabledからsites-availableへのシンボリックを作成・削除する必要があります。

さくらVPS

【 Aレコード 】 ドメインIPアドレスに置き換えるレコード。一番基本的なレコードになります。 【 MXレコード 】 メールエクスチェンジの略で、メールサーバのホスト名を記載するレコードです。 【 CNAMEレコード 】 キャノニカルネームの略でドメインを別のドメインに置き換えるレコードです。特定のドメインを別のドメインに転送する場合に使用します。


  • sslファイルの設定は以下を参考に設定

"listen 80" と "listen 443"をわけるのではなく、一つのディレクティブに混ぜ込む

server {
  listen 80;

  #SSL
  listen 443 ssl;
  ssl_certificate /etc/ssl/bar.fjord.com/ssl.crt/server.crt;
  ssl_certificate_key /etc/ssl/bar.fjord.com/ssl.key/server.key;
  
  server_name bar.fjord.com;
  access_log /home/ymmtd0x0b/public_html/bar.fjord.com/log/access.log;
  error_log /home/ymmtd0x0b/public_html/bar.fjord.com/log/error.log;

  location / {
    root /home/ymmtd0x0b/public_html/bar.fjord.com/public/;
    index index.html;
  }
}

nginxサーバを起動するとエラー、journalctl -xeを指定すると以下のようなログが得られる

Mar 01 17:54:16 ik1-107-60499 nginx[4511]: nginx: [emerg] cannot load certificate "/etc/ssl/server.crt": PEM_read_bio_X509_AUX() faile>

パーミッションを設定(制限)

$ sudo chmod 700 /etc/ssl/dharmaskop.com/ssl.key
$ sudo chmod 400 /etc/ssl/dharmaskop.com/ssl.key/server.key

サーバが立ち上がった

<順序>

  1. サーバ管理者が秘密鍵ファイル(server.key)を作成する。
  2. サーバ管理者が秘密鍵ファイルから、公開鍵(Public Key)と、秘密鍵のハッシュを組み合わせて、証明書署名要求ファイル(server.csr)を作成する。サーバ管理者はこの証明書署名要求ファイルを認証局に送付する。
  3. 認証局は自分の秘密鍵で証明書署名要求ファイルに署名してサーバ証明書(server.crt)を作成し、返却する。

  4. server.key/server.crt/cerver.csrはコピーして他のサイトでも流用可能

sshでの接続

ssh caminotak@192.168.0.126 -p 80
ssh_exchange_identification: Connection closed by remote host

以前のログから見直してできました。助かった。

taku-no-MacBook-Pro:~ takunaka$ ssh -p 8888 caminotak@192.168.0.126
Linux debian 5.10.0-10-amd64 #1 SMP Debian 5.10.84-1 (2021-12-08) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Feb 26 11:33:10 2022
caminotak@debian:~$ 
  • ssh接続しているポートの確認 etc/ssh/ sshd.config(ssh.configではない)

    • ssh.config :他のサーバーに接続するときの設定 (クライアント)
    • sshd.config : 他のサーバーから接続されるときの設定(デーモン)

      デーモンはOSに登録され、コンピュータやOSの起動(ブート)時に一緒に起動され、実行状態となる。強制終了など特殊な場合を除いて基本的に利用者が直に操作することはない。HTTP通信を処理する「httpd」のように、デーモンの実体となる実行可能ファイルの名称には末尾に「d」を付ける習慣がある(必ずしも従う必要はないため例外も多い)。ちなみに、Windowsではほぼ同様のプログラムを「サービス」という。

  • diffコマンド(比較したい二つのファイル) ファイルの違いを表示

  • sshdのファイル構文をチェック : # sshd -t
  • sshd : の設定を反映 # service sshd restart
  • 変更しただけではssh接続できず、おそらく鍵の再設定が必要(ポートを8888に戻して再接続)

  • /etc 設定ファイルをおくディレクト

  • /lib 共有ライブラリ

  • etc/hostsでローカルで接続する場合のipアドレスを設定する。

TOPICS

  • /var/log/auth.log にログが載っている sudo lessで表示
Feb 26 11:53:49 debian systemd-logind[352]: New session 9 of user caminotak. <#Debianから直接操作>
Feb 26 12:06:59 debian sudo: caminotak : TTY=tty2 ; PWD=/home/caminotak ; USER=root ; COMMAND=/etc/init.d/nginx stop

Feb 26 12:06:59 debian sudo: pam_unix(sudo:session): session opened for user root(uid=0) by caminotak(uid=1000)

Feb 26 12:06:59 debian sudo: pam_unix(sudo:session): session closed for user root

Feb 26 12:07:28 debian sudo: caminotak : TTY=pts/0 ; PWD=/home/caminotak ; USER=root ; COMMAND=/etc/init.d/nginx start <#クライアントから遠隔操作>

ttyとは端末デバイスttyコマンドを入力すると自分のコマンド名が表示される。ptsSSHtelnetで接続してる仮装端末、ターミナル。

ttyはteletypewriter(テレタイプライター) ptsは擬似端末 (pseudo-terminal)

caminotak@debian:/var/log$ tty
/dev/pts/0
caminotak@debian:/var/log$ tty
/dev/tty2
  • ログイン中のユーザを表示 : $ w
  • プロセスログを確認 : $ ps
  • tty同士でコマンドのやりとりができるソース


  • ファイルディスクリプタ

    ファイルディスクリプタとは、プログラムがアクセスするファイルや標準入出力などをOSが識別するために用いる識別子。ソース

  • DNS(domain name system)サーバ = ネームサーバ : ドメインを受け取りipアドレスを返すサーバ ドメイン名を利用するときにドメイン名情報の中に[ネームサーバ情報]を登録する

  • VPSサーバ:仮装専用サーバ/Virutual Private Server サーバーを共有するも、サーバの中に仮想化したサーバを設置し専用サーバのような使い方ができる 共有サーバとの違いはOSの選択やアプリの構築ができる。 コマンド操作が必要になる。
  • バイナリとソースパッケージ
    • バイナリパッケージ:コンパイラによって変換されたものを「バイナリ」という。あらかじめソースがコンパイルされている(ビルドされている)
    • ソースパッケージ:プログラムを動かすために必要なファイルの集まったものGihubなどからダウンロードできる
  • ソースファイル:人間が書いたプログラムのソースコードが書いてあるファイル
  • TARファイル : Tape ARchive / ディレクトリツリーを単一のファイルとしてする。tarでパッケージしてGNU zipしたものをtar.gzという


  • クラスメソッドは「クラスオブジェクトの特異メソッド」である (クラス名)::(メソッド名)/File::exist?表現する
  • Rubyではクラス名も定数の一つなので、エラーもuninitialized constantで表示される
  • Minitestではsetupメソッドを定義するとテストメソッドに実行前に毎回呼び出される。
def setup
  @umeda = Gate.new(:umeda)
  @juso = Gate.new(:juso)
  • クラス内のメソッドの中でクラスメソッドを(クラス名).(メソッド名)あるいはself.(メソッド名)で呼びだすことができる。
  • ipアドレスの確認方法 : ip a/linux, ifconfing/mac
  • SSH(Secur Shell) : ネットワーク接続された遠隔操作するためのソフトウェアあるいはプロトコル
  • SSL(Secured Socket Layer) : ブラウザとサーバーの間のデータ通信を暗号化し送受信するプロトコル

学習記録 (2/17 -24 )

2/17

  • ls -lコマンドのパーミッションの後ろにつく記号

    (スペース) 通常のUnixのアクセス権限だけが有効 .(ドット) SELinuxのアクセス権限が付いている +(プラス) その他のアセス権限が付いている。例えば、sambaで公開しているファイルにWindows上で権限設定したりすると付く。

  • @はmac拡張属性を表す

  • file.statオブジェクトのパーミッション取得と進数変換

(rdbg) p a.mode    # command
=> 16877
(rdbg) p a.mode.to_s(8)    # command
=> "40755"
(rdbg) puts "0%o" % a.mode     # ruby
040755
nil
(rdbg) puts a.mode.to_s(8)    # ruby
40755
nil
(rdbg) printf  "0%o\n" , a.mode     # ruby
040755
nil

#進数%oの前に0を入れることで0が左にはいる
  • printf:書式を指定して出力。戻り値はnil
('商品情報: カテゴリー %s 型番 %d', 'bag', 10111)
#[実行結果]
商品情報: カテゴリー bag 型番 10111
  • 桁数を右揃えで指定 : printf("%5s","abc") 左揃え : printf("%-5s","abc")
#数値型の桁数を指定する場合も、文字数を指定する場合同様です。

puts "12345"
printf("%5d",123)
#[実行結果]
12345
  123 

#数値型の場合は、空白に0を詰めて表示できます。

puts "12345"
printf("%05d",123)
#[実行結果]
12345
00123
#このように、5桁に対して足りない部分は0で補われています。
  • springf(戻り値のみ): printfメソッドがコンソールに対して直接出力するのに対して、sprintfメソッドは文字配列に対して出力するためのメソッドになります。

printfとは 与えられた引数を指定フォーマットの文字列として出力します。 似たような名前のsprintfは「文字列として返す」のに対して、今回のprintfは「文字列として出力(表示)する」点が異なります

2/18

<正規表現>

  • \dは任意の半角数字1文字 \dは\wに含まれる
  • \wは英単語を構成する文字+アンダースコア [a-zA-Z0-9_]
  • \d{2,5} : 半角数字が2-5文字
  • [AZ] : AまたはZ、またはの間になんの仕切りもなく並んでいるので連続している文字列に見えるのに注意
  • [A-Z] : AまたはBまたは...またはZ
  • [-AZ]、[AZ-] : -またはAまたはZ
  • 正規表現を使うときには//で囲む
  • [-AZ]? : -またはAまたはZ または無し
  • (-AZ)? : 文字列'-AZ' または無し
  • . : 任意の1文字
  • + : 直前の文字が1文字以上
  • * : 0文字以上 .* =任意の文字0文字以上
  • \Aは文字列の始まり、\zは文字列の終わりを意味する
  • ^: 以外の ^A*=`A以外の任意の文字
  • ^: 行頭
  • ?: 最短マッチ *?/.?/+? 貪欲さを消す
  • $ : 行末 ^ +$ = 行末まで半角スペースが続く文字列、改行文字は含まれないので行末に\nを指定することもできる。
  • \t:タブを表すメタ文字
  • \s: 半角、タブ空白文字全般 \s = [ \t\r\n\f]
    • Rubyの場合は半角スペース( )、タブ文字(\t)
    • 改行文字(\n)、復帰文字(\r)、改ページ文字(\f)
    • かっこで囲って |でつなぐ ^.+heroku\/(api|scheduler).+$



  • scanメソッド: オブジェクトと同一の結果を配列で返す 引数の中に正規表現が入る場合は//で囲む

  • grepメソッド(配列ー配列) :配列.grep(オブジェクト) 正規表現に対してはパターンにマッチした要素を返す

  • キャプチャしたものを出力するには`gsub(検索文字列、キャプチャ()入り,'\1, \2')

mの中に3つのマッチデータが格納されていてハッシュと同じ方法で取得できる。

p m 
=> #<MatchData "2016-05-08" year:"2016" month:"05" day:"08">

次のような形も可能

s = '2016-05-08'
if /(?<year>\d+)-(?<month>\d+)-(?<day>\d+)/ =~ s
  # 名前付きキャプチャがそのままローカル変数になる
  puts "year: #{year}, month: #{month}, day: #{day}"
  # => year: 2016, month: 05, day: 08
end

理論演算子=~ : 正規表現オブジェクト =~ string

2/19

  • lsコマンドの揃えはそれぞれの列の再材の

  • 左揃え

a = 7
printf("%0#{a}d",123)
printf("%#{a}d",123)
#=> 0000123    123

dsに変えると文字列が表示できる。


  • テストファイルの記述方法 変数を使っている
  def test_score1
    marks = '6,3,9,0,0,3,8,2,7,3,X,9,1,8,0,X,6,4,5'
    assert_equal 139, calculate_score(marks)
  end


users = []
users << User.new('Alice','Ruby',20)
users << User.new('Bob','Python',30)

p users    # command
=> [#<User:0x00000001116147e0 @age=20, @first_name="Alice", @last_name="Ruby">, #<User:0x0000000111614718 @age=30, @first_name="Bob", @last_name="Python">]

p users[0]    # command
=> #<User:0x00000001116147e0 @age=20, @first_name="Alice", @last_name="Ruby">
  • クラスの中にメソッドを作って初めてそのインスタンスにメソッドを適用できる。

  • initializeはデフォルトでprivateで外部から呼び出せない

  • セッターがインスタンス変数に直接代入される時だけattr_accessorを使うことができる。

<残りの課題>


.(ドット) SELinuxのアクセス権限が付いている +(プラス) その他のアセス権限が付いている。例えば、sambaで公開しているファイルにWindows上で権限設定したりすると付く


ディレクトリにスティッキービットを付与: $ chmod +t free_dir ファイルにもw権限があるユーザーに対しファイル削除を制限(ファイル所有者以外)

taku-no-MacBook-Pro:lib takunaka$ ls -l@
total 48
-rw-r--r--@ 1 takunaka  staff   310 Feb 18 13:31 class.rb
    com.apple.metadata:_kMDItemUserTags   42 
-rw-r--r--@ 1 takunaka  staff   160 Feb 15 15:01 filestat.txt
    com.apple.metadata:_kMDItemUserTags   42 
-rw-r--r--  1 takunaka  staff  1472 Feb 18 14:00 ls4.rb
-rw-r--r--@ 1 takunaka  staff  2891 Feb 18 17:55 ls5.rb
    com.apple.metadata:_kMDItemUserTags   42 
-rw-r--r--@ 1 takunaka  staff    81 Feb 18 12:54 printf
    com.apple.metadata:_kMDItemUserTags   42 
-rw-r--r--@ 1 takunaka  staff   342 Feb 18 16:34 regexp.rb
    com.apple.metadata:_kMDItemUserTags   42 
taku-no-MacBook-Pro:lib takunaka$ ls -l
total 48
drwxr-xr-x  2 takunaka  staff    64 Feb 16 14:32 00
-rw-r--r--@ 1 takunaka  staff   310 Feb 18 13:31 class.rb
-rw-r--r--@ 1 takunaka  staff   160 Feb 15 15:01 filestat.txt
-rw-r--r--  1 takunaka  staff  1472 Feb 18 14:00 ls4.rb
-rw-r--r--@ 1 takunaka  staff  2891 Feb 18 17:55 ls5.rb
-rw-r--r--@ 1 takunaka  staff    81 Feb 18 12:54 printf
-rw-r--r--@ 1 takunaka  staff   342 Feb 18 16:34 regexp.rb


  • メソッドの表記法 '#' : クラスの中のインスタンスメソッド String#to_i '.'あるいは'::' : クラスメソッド File.exist?(File::exist?)


2/20

メソッド分割

  • lsコマンド 時刻で並べ替え -tオプション

  • DateTimeクラス : requre'date'が必要。現在時刻DateTime.now

require "date"

d1 = Date.today
d2 = Date.new(2007, 3 ,14)

print("本日の日付:", d1, "¥n")
print("3日後の日付:", d1 + 3, "¥n")
print("5日前の日付:", d1 - 5, "¥n")
print("2ヶ月後の日付:", d1 >> 2, "¥n")
print("6ヶ月前の日付:", d1 << 6, "¥n")
print("本日の日付と2007/03/14との差は", d1 - d2, "日です¥n")


  • Arrayクラスメソッド : Array(3)3つの空配列の入った配列を作る array = Array.new(3){"Red"}それぞれの配列にブロック内の処理を行う

  • 配列を作るとき、[ ]の代わりに%w( )、%i( )を使う

  • レビューの指摘

    • 配列を配列を作る場合mapを使う
    • 配列の中にn個の空配列を作る : [[]] * n
    • if-elseを分割
    • メソッドはまとめてファイルの最初の方に定義する

printf("",,,) : ""の中に文字列(式展開を含む)を入力し、そのあとのカンマに%部分に入る値を入力していく


  • クラス/メソッド/変数関連
    • インスタンス変数 : クラスの中に定義されていても、クラスメソッドからはアクセスできない(インスタンスからのみ)
    • クラスインスタンス変数(イニシャライズの外で定義したインスタンス変数): クラスメソッドからアクセスできるが、インスタンスメソッドからはアクセスできない。
    • クラス変数 : クラスの中の変数でアクセスすることでインスタンスの中の変数の値も変化する。
    • クラス名::クラス定数で外部からクラス定数にアクセスできる
    • インスタンスメソッドはクラス内のメソッドの中でしか呼び出せない、クラスメソッド、クラス内では呼び出せない
    • クラスインスタンス変数はクラスの中のインスタンスメソッド以外の範囲で参照できる、クラスメソッドからもアクセス可能
    • クラス変数はそのどちらからもアクセス可能


  • git コミット修正メソッド
    • git reset --soft HEAD^ : コミットを戻す(ステージのまま)
    • git reset HEAD : ステージを戻す
    • git amend : コミットメッセージを取り消す
    • git revert : コミットを打ち消す新たなコミット


  • 以下のようなコードを書いて、他のメソッドの初期に実行するとinitializeメソッドのような動きをする。(@が必要) (後記:ハッシュでもよし)
  def dataspace(files)
    @nlink_space = files.map { |file| file.nlink.size }.max + 1
    @uid_space = files.map { |file| file.uid.size }.max + 1
    @gid_space = files.map { |file| file.gid.size }.max + 2
    @size_space = files.map { |file| file.size.size }.max + 2
  end

2/21

< TOPIC >

  • divmod : 商と余を返す。14.divmod(3) => [4,2]
  • a, b = 3 ,4[3,4]を返しa = 3b = 4となる
  • a , b = [3,4] もまたa = 3b = 4となる
  • 配列に*をつけるとその場でflattenできる
  • 代入自体が戻り値を持つのでif分の条件に使うことができる
  • レシーバーがnilであっても&.を使うとnilを返す、no methodエラーにならない。
  • limit ||=10 limitがnilかfalseであったなら、10を代入する
  • nilガード先の変数を begin/endで囲い複数行の記述ができる
  • あえてinitializeをせずに手動初期化のメソッドを作りそこに||=を入れることで重い初期化を回避できる
  • 例外処理 rescue => e 文字列(エラー名)が変数eに代入されている。
begin
  1 / 0
rescue => e
  puts "何か問題が発生しました。"
  p e
end
puts 
  • rescueの後にエラーのクラスを指定することでそのエラーだけrescueする
begin
  1 / 0
rescue ZeroDivisionError
  puts "対象の例外やー。"
end

< TOPIC >

  • mapで出力する配列をflatにするにはflat_mapを使用する
  • ブロック内でfalse/nilの値は返さないfilter_map
  • concatで配列を結合すれば、最後にflattenしなくて済む
  • カウンタつき繰り返し処理、 _with_indexに引数()をつけるとその値からカウントが始まる
  • each_with_object オブジェクトを作って出力する -if __FILE__ == $0という分岐は、スクリプトが実行されているパスとソースファイルが同じであるという意味。  この分岐のついたメソッドは、require先のファイルでは実行されない __FILE__とは”現在のソースファイル名”の意味 $0現在実行中のスクリプトの名前を表す文字列 $PROGRAM_NAMEも同義

  • getoptsメソッドでのオプションの取得

    • オプションはoptions = ARGV.getopts('a','r','l')の形で取れる optionにはハッシュで{'a'=>ture,'r'=>false,'l'=true}のような形で出力される
    • 引数をつける(オプションが 'a'から'a:'になる)とハッシュの値が引数の値になる
#!/usr/bin/env ruby
require 'optparse'

options = ARGV.getopts('a:')
puts options
% ./arg.rb -a 111
{"a"=>"111"}


p /abc/ =~ "abc"          # 0
p /abc/ =~ "pabc"         # 1
p /abc/ =~ "ppabc"        # 2
p /abc/ =~ "ppabcppabc"   # 2
p /abc/ =~ "pab"          # nil


  • initializeなしのattr_accessor : 外部から入力する。イニシャライズ時に値を入れなくもいい。
class Cat
 attr_accessor : name

 def cat_name
  "#self.name"
  end
end

に対し

cat1 = Cat.new
cat1.name = 'たま'
cat1.cat_name #=> たま
  • 可長変引数

    • *をつけた引数は制限がなく配列として認識される、ローカル変数として渡される方は*をつけない
def variadic(arg1, arg2, *others)
  p arg1
  p arg2
  p others
end

variadic(1,2,3,4,5)
  # 1
  # 2
  # [3, 4, 5]
variadic(1,2)
  # 1
  # 2
  # []


  • **引数 引数をキーワードと値にすることで、ハッシュに格納される。
def keyword_args(**keywords)
  puts keywords
end

keyword_args(a:1,b:2)
#=> {:a=>1, :b=>2}

引数にキーワードと値が代入される


< TOPIC >

  • max_number = [max_number , a].max をeachで回すと回すと配列の最大数が得られる
  • 組み合わせは素直にMODE_TABLEを使う (8進数から2進数に変換する必要がない)


wcコマンドについて

  • 行数と単語数とバイト数、ファイル名を表示
  • 複数ファイルを指定した時には改行し結果を返し、最後の行にトータルを表示

  • コマンドラインの引数を取得 ARGVは引数の入った配列を表す

  • 標準入力 : IOオブジェクト 組込定数STDIN/グロバル変数$stdin

  • 標準出力 : IOオブジェクト 組込定数STDOUT/グロバル変数$stdin
  • 標準エラー出力 : STDERR/ $stderr
  • tty?メソッド、コンソールに関連づけられている場合、tty?trueになる

  • getsは標準入力を受け取る。$stdinオブジェクトが省略されている。

  • 文字列のバイト数の取得は.bytesize
  • gets/readline : 標準入力を「文字列」として取得
  • readlines : 最後の改行まで全てを「配列」として取得
  • read : 最後の行まで全てを[文字列]として取得
  • getsはブロックの入力も標準入力として受け取る。
File.open("data001.txt"){|f|
  p f.gets  # 1行目
  p f.gets  # 2行目
  p f.gets  # 3行目
}

getsは読み込めない行はnilを返すが、readlineはEOFErrorを返す

  • readlineはファイルの中身の文字列を読んでいる。
  • 引数に複数のファイルが指定されている場合はその中身を直接繋げて読み込んでいる。

2/24

- Pathnameクラス Pathnameオブジェクトはパス名を示す

  • テストしやすいコードしにくいコード 純粋なrubyコードはテストしやすい -> libに入れる ターミナルの情報(画面の幅など)はテストコードに反映しにくい ->binに入れて分ける
  • rubocop.ymlでrubocopを使用する対象ディレクトリをコントロールする
  • クラスの中でインスタンス変数を使わなくても、ハッシュを使ってもよい
  • ”文字列に+で順次入れ込んでいく”ではなく、”文字列を配列に入れんんで最後のjoinする”というロジックがより良い
  • %i[]ではハッシュを作る
  • 配列は*で展開
  • formatメソッドの実例
 `format('%<mon>2d %<mday>2d %<hour>02d:%<min>02d', mon: mtime.mon, mday: mtime.mday, hour: mtime.hour, min: mtime.min)`
  • テストの作成
    • Minitestはtest_で始まるメソッドを探して実行する
    • test_`で始まるメソッドは複数定義するvことができる
    • assert_equal a, b (a == bであればパス)
    • assert a (aが真であればパス)
    • refute b (bが偽であればパス)
    • assert_output : 標準出力の内容を検証する -linesメソッド(Stringクラス) : 文字列の改行までを要素にした配列を返す -countメソッド : 配列の要素数を数える、引数で数える要素を指定

学習記録 (2月15-16日)

2/16

(rdbg) p a.mode    # command
=> 16877
(rdbg) p a.mode.to_s(8)    # command
=> "40755"
(rdbg) puts "0%o" % a.mode     # ruby
040755
nil
(rdbg) puts a.mode.to_s(8)    # ruby
40755
nil
(rdbg) printf  "0%o\n" , a.mode     # ruby
040755
nil

#進数%oの前に0を入れることで0が左にはいる

0bや0xなど接頭子が付いた文字列が必要な場合は、kernelのsprintfを使うのが簡単だ。以下のようにして2進、8進数、10進数、16進数の文字列を得る。

p sprintf("%#b", 255) #=> "0b11111111"
p sprintf("%#o", 255) #=> "0377"
p sprintf("%#d", 255) #=> "255"
p sprintf("%#x", 255) #=> "0xff"

sprintfはString#%として書くこともできる。ただこれ、%がsprintfというのが直感的でなく、可読性があまり良いとは思えないので、個人的には好きではない。

p "%#b" % 255 #=> "0b11111111"
p "%#o" % 255 #=> "0377"
p "%#d" % 255 #=> "255"
p "%#x" % 255 #=> "0xff"
  • printf:書式を指定して出力。戻り値はnil
printf('商品情報: カテゴリー %s 型番 %d', 'bag', 10111)
#[実行結果]
商品情報: カテゴリー bag 型番 10111

桁数を右揃えで指定 : printf("%5s","abc") 左揃え : printf("%-5s","abc")

#数値型の桁数を指定する場合も、文字数を指定する場合同様です。

puts "12345"
printf("%5d",123)
#[実行結果]
12345
  123 

#数値型の場合は、空白に0を詰めて表示できます。

puts "12345"
printf("%05d",123)
#[実行結果]
12345
00123
#このように、5桁に対して足りない部分は0で補われています。
  • springf:printfメソッドがコンソールに対して直接出力するのに対して、sprintfメソッドは文字配列に対して出力するためのメソッドになります。戻り値を出す。

printfとは 与えられた引数を指定フォーマットの文字列として出力します。 似たような名前のsprintfは「文字列として返す」のに対して、今回のprintfは「文字列として出力(表示)する」点が異なります

p sprintf("明日、%sの最高気温は%d度です。","サムライ村",33)
#[実行結果]
"明日、サムライ村の最高気温は33度です。"
  • これを使いたい/ printで改行なしで。
#また、その際には変数展開と呼ばれる記法を使用して、ハッシュの中身を展開します。
hash = {ruby:"Rails",php:"CakePHP",python:"Django"}
hash.each do |key,value|
puts "#{key}の有名Webフレームワークは#{value}です。"
end
#[実行結果]

rubyの有名WebフレームワークはRailsです。
phpの有名WebフレームワークはCakePHPです。
pythonの有名WebフレームワークはDjangoです

2/17

  • 正規表現
  • \dは任意の半角数字1文字 \dは\wに含まれる
  • \wは英単語を構成する文字+アンダースコア [a-zA-Z0-9_]
  • \d{2,5} : 半角数字が2-5文字
  • [AZ] : AまたはZ、またはの間になんの仕切りもなく並んでいるので連続している文字列に見えるのに注意
  • [A-Z] : AまたはBまたは...またはZ
  • [-AZ]、[AZ-] : -またはAまたはZ
  • 正規表現を使うときには//で囲む
  • [-AZ]]? : -またはAまたはZ または無し
  • (-AZ)? : 文字列'-AZ' または無し
  • '.' : 任意の1文字
  • '+' : 直前の文字が1文字以上
  • * : 0文字以上 '.*' =任意の文字0文字以上
  • '\A'は文字列の始まり、'\z'は文字列の終わりを意味する
  • '^': 以外の '^A'*='A以外の任意の文字'
  • ’^’: 行頭
  • ’?’: 最短マッチ *?/.?/+? 貪欲さを消す
  • '$' : 行末 '^ +$' = 行末まで半角スペースが続く文字列、改行文字は含まれないので行末に'\n'を指定することもできる。
  • '\t':タブを表すメタ文字
  • '\s': 半角、タブ空白文字全般 \s = [ \t\r\n\f]
    • Rubyの場合は半角スペース( )、タブ文字(\t)
    • 改行文字(\n)、復帰文字(\r)、改ページ文字(\f)
    • かっこで囲って |でつなぐ ^.+heroku\/(api|scheduler).+$

  • '==','===','eql!''equal?'の比較.

    効果 / 使用場面 / 再定義 == 同値性のチェック 同値性のチェック ○ === 同値性のチェック(所属性) case式 ○ eql? 同値性のチェック(厳密) Hashキーの比較 ○(※) equal? 同一性のチェック 同一性のチェック ×

  • equal?はobject_idのチェックを行う

  • .scanメソッド: オブジェクトと同一の結果を配列で返す 引数の中に正規表現が入る場合は//で囲む

  • grepメソッド(配列ー配列) :配列.grep(オブジェクト) 正規表現に対してはパターンにマッチした要素を返す

  • 正規表現をメタ文字とも呼ぶ

  • 正規表現に()を使うとその部分かキャプチャされ連番がつけられる

正規表現で名前付きキャプチャを使う

  • 名前付きキャプチャ : (?<キー>値)でキャプチャしてk<キー>値で指定

    s = '2016-05-08' 
    
      puts s.gsub(/(\d+)-(\d+)-(\d+)/, '\1年\2月\3日')
    # => 2016年05月08日
    

    連番を使う場合のキャプチャは ( ) ですが、名前付きキャプチャを使う場合は次のような構文を使います。

  
  (?<name>pattern)

   puts s.gsub(/(?<year>\d+)-(?<month>\d+)-(?<day>\d+)/, '\k<year>年\k<month>月\k<day>日')
  • キャプチャしたものを出力するには`.gsub(検索文字列、キャプチャ()入り,'\1, \2')

  • matchメソッド (文字列)>MatchDataクラス): オブジェクト名.match(正規表現) 文字列の検索に用いる matchメソッドはMatchDataが格納され、pre_matchおよびpost_match メソッドでその前後の文字列を出力する

s = '2016-05-08'
if m = s.match(/(?<year>\d+)-(?<month>\d+)-(?<day>\d+)/)
  year  = m[:year]
  month = m[:month]
  day   = m[:day]
  puts "year: #{year}, month: #{month}, day: #{day}"
  # => year: 2016, month: 05, day: 08
end

mの中に3つのマッチデータが格納されていてハッシュと同じ方法で取得できる。

p m 
=> #<MatchData "2016-05-08" year:"2016" month:"05" day:"08">

次のような形も可能

s = '2016-05-08'
if /(?<year>\d+)-(?<month>\d+)-(?<day>\d+)/ =~ s
  # 名前付きキャプチャがそのままローカル変数になる
  puts "year: #{year}, month: #{month}, day: #{day}"
  # => year: 2016, month: 05, day: 08
end
  • プログラムの堅牢性 二つの対応するデータの運用は、配列よりもハッシュ、ハッシュよりもクラスの方がズレが生じにくい。

  • %w記法 %w()の中に値を入れる、スペースあけで配列を作る

irb(main):002:0> a = %w(bbb ccc)
=> ["bbb", "ccc"]
  • %W記法は式展開される (""のようなもの?)

  • q/Qはクオート,i/Iはシンボル(%sもシンボル)、%xはコマンド出力

2/13

  • wcコマンドとはテキストファイルの行数や単語数、文字数を数えるコマンド。単語は空白や改行文字で区切られたものを数える。

    • c/--bytes バイト数を表示
    • m/--chars 文字数を表示 (マルチバイトに対応)
    • l/--lines 改行の数を表示
    • w/--words 単語数を表示
    • L/ --max-line-length 最も長い行の長さを表示
  • 三項演算子

var = "文字列"

var.class == String? "varはStringです" : "varはStringではありません"
  • 後置if
age = 21
puts "adult!" if age >= 18 #=> adult!
  • pluckメソッド :配列内のハッシュのキーを指定して、それぞれのハッシュから取り出し配列にして返す。
  b = [{name: 'b1', address: 'b1@example.jp'}, {name: 'b2', address: 'b2@example.jp'}]
  > b.pluck(:address) 
  # => ["b1@example.jp", "b2@example.jp"]
  • プルリクエストの取り消し pull reqestの画面の一番下にコメントしてclose and commentをクリック

  • class TrueClass/FalseClass true/falseはそれぞれのクラスの唯一のインスタンス

  • 配列から文字列への変換 ["ls4_test.rb"].to_s"[\"ls4_test.rb\"]"に変換される

  • テストコードでコード内のメソッドを確認

2/15 - パース = 構文解析

  • ClassIO : 基本的な入出力機能のためのクラス

  • File.statとFile::Statの違いは何?

Rubyで容量やパーミッションなどファイルの情報を取得するにはFile.statメソッドを使用する。File.statメソッドはファイルの情報を格納した、File::Statオブジェクトを返す。

  • File:Statクラス オブジェクトを作るときはFile:Stat.new(引数) メソッドを使うときは、File.stat(引数)

  • クラス File::StatSリファレンス

    • 特異メソッド ファイルの情報を格納したオブジェクトのクラス new(path) -> File::Stat pathに関するFile::Statオブジェクトを生成して返す。File.statと同じ

    • inspectメソッド オブジェクトを文字列で返す。


  • to_hメソッド 配列の中の配列をキーと値に変換
  human = [["name", "pikawaka"], ["age", 25]]
human.to_h
=> {"name"=>"pikawaka", "age"=>25}

シンボルでも指定可能

human = [[:name, "pikawaka"], [:age, 25]]
human.to_h
=> {:name=>"pikawaka", :age=>25}
  • 文字の削除

    • delteメソッドは指定した文字列ではなく、文字列に含まれるすべての文字を削除する
  • ls -lコマンドのパーミッションの後ろにつく記号

    (スペース) 通常のUnixのアクセス権限だけが有効 .(ドット) SELinuxのアクセス権限が付いている +(プラス) その他のアセス権限が付いている。例えば、sambaで公開しているファイルにWindows上で権限設定したりすると付く。

  • @?は

File::Statの値を変換するメソッドをつくる

e = "#{a.ftype}#{a.mode} #{a.nlink} #{a.uid} #{a.gid} #{a.size} #{a.mtime}"
  • ファイルタイプ
def ftype(name)
{ 
  'directory' =>  'd',
  'flie' => '-'
}[name]

学習記録 (2月12-14日 )

2/12

2/13

  • library optparse
  • OptionParser オブジェクト opt を生成する。
  • オプションを取り扱うブロックを opt に登録する。
  • opt.parse(ARGV) でコマンドラインを実際に parse する。
opt = OptionParser.new
opt.on('-a', '--add ITEM', 'add an item') { |v| puts "Add #{v}" }
opt.on('-d', '--del ITEM', 'delete an item') { |v| puts "Delete #{v}" }
opt.parse(ARGV)
require 'optparse'

options = ARGV.getopts('a')
puts options

コマンドラインのオプションがaの場合option => trueとなる

require 'optparse'

options = ARGV.getopts('a','r','l')
puts options

コマンドラインのオプションがaの場合option => {"a"=>true, "r"=>false, "l"=>false}ハッシュ値が戻る

  • ハッシュのメソッド
    • .keys キーを配列で返す
    • .values 値を配列で返す
    • .to_a キーと値をそれぞれ配列にした配列を返す
    • ハッシュオブジェクト[キー]で値を取り出す(キーに:はいらない)


  • case/when文の評価方法
    • case オブジェクト/when 条件
    • case / when オブジェクトと条件の評価式
    • case "a" == true の場合は == tureを省略できる。


  • class Dir : ディレクトリ操作を行うためのクラス
    • globメソッド : パターンにマッチするファイル名を文字列の配列として返す。glob(pattern, flags = 0, base: nil, sort: true)
    • 配列で返すために、戻り値をブロックで処理することができる
      • [PARAM] pattern: パターンを文字列か配列で指定します。配列を指定すると複数のパターンを指定できます。
    • [PARAM] flags: File.fnmatch に指定できるフラグと同様のフラグを指定できます。このフラグを指定することでマッチの挙動を変更することができます。 Dir.glob("*", File::FNM_DOTMATCH)で隠しファイルを取得
p File.fnmatch("list*", "list.txt")     # true
p File.fnmatch("*list*", "./list.txt")  # false
p File.fnmatch("*list*", "./list.txt",         File::FNM_DOTMATCH) # true
p File.fnmatch("{my,your}file*", "myfile.txt", File::FNM_EXTGLOB)  # true
  • 複数のパターンを指定する例
p Dir.glob(["f*", "b*"]) # => ["foo", "bar"]
p Dir["f*", "b*"]        # => ["foo", "bar"]

2/14

Cookie

  • stateless protocol : リクエストに対してレスポンスを配信すすると直ちに閉じられる
  • HTTP/1.0からHTTP Cookieが付加される
  • Cookieはサーバからブラウザに送られ、ブラウザの中に保存される。
  • 消去される期限はexpire属性に定義されている。
  • 短時間のセッションで有効なクッキーがセッションクッキー(数分)。ブラウザが閉じられると、終了する。
  • 長期間(週あるいは月単位)で有効なのがパーシステントクッキー、ブラウザを終了してもブラウザ内に保存される。
  • 1st party cookieドメインから送信され、3rd party cookieは広告などが送られてくる別ドメインから送られてくる。
  • サードパーティcookieは広告のために個人の情報をトラッキングできる。


  • reverseメソッド: instance method Array#reverse 配列自信を逆順にする !をつけることで破壊的に変換する。

  • splitメソッド: instance method String#split 引数で分けて配列にして出力

  • FileUtilsのメソッドは、UNIXコマンドに対応しているのでわかりやすい


ファイルとディレクトリを操作する

カレントディレクトリのディレクトリやファイルを操作する。

  • singleton method File.fnmatch: Fileクラス ファイル名のパターンマッチを行う マッチすれば真を返す fnmatch(pattern. path, flags = 0) flags: デフォルトは0

    • FNM_NOESCAPE
    • FNM_PATHNAME
    • FNM_CASEFOLD
    • FNM_DOTMATCH
    • FNM_EXTGLOB
  • singleton method Dir.[]: Dirクラス

  • パターンにマッチするファイル名を文字列の配列として返す Dir[*pattern, base: nil, sort: true] Dir.glob(pattern, flags = 0 , base: nil, sort: true)
# 一般的な例
p Dir.glob("*")          #=> ["foo", "bar", "baz"]
p Dir.glob("./b*")       #=> ["./bar", "./baz"]      先頭に "./" が付いている。
p Dir.glob("*/")         #=> ["foo/"]                ディレクトリのみにマッチする。
p Dir.glob("wrong_name") #=> []                      マッチしないと空の配列を返す。

Dir.glob("b*") {|f| p f }

#=> "bar"
#   "baz"

# 複数のパターンを指定する例
p Dir.glob(["f*", "b*"]) # => ["foo", "bar"]
p Dir["f*", "b*"]        # => ["foo", "bar"]

# ワイルドカードの例
Dir.glob("*")            #=> ["foo", "bar"]
Dir.glob("fo?")          #=> ["foo"]
Dir.glob("[^f]*")        #=> ["bar"]
Dir.glob("{b,f}*")       #=> ["bar", "foo"]

# ベースディレクトリの例
rbfiles = File.join("**", "*.rb")
Dir.glob(rbfiles)                   #=> ["main.rb",
                                    #    "lib/song.rb",
                                    #    "lib/song/karaoke.rb"]
Dir.glob(rbfiles, base: "lib")      #=> ["song.rb",
                                    #    "song/karaoke.rb"]


ls -lオプション

  • 以下が表示される
  • ファイルタイプ :ftype
  • パーミッション : modeの5-7桁目
  • ハードリンクの数 :nlink
  • オーナー名 :uid 番号表示
  • グループ名 : gid 番号表示
  • バイトサイズ : size
  • タイムスタンプ : mtime
  • ファイル名 そのまま取得

  • Fileクラスでファイル操作/IOクラスを継承している

file = File.open("doughnut.csv", "r:UTF-8")
  • ファイルの情報を格納した「File::Stat」クラスのオブジェクトを取得
  stat = File.stat("/Users/miro/Documents/RubyProjects/MyRuby/doughnut.csv")
p stat.file? # true
p stat.atime # 2017-05-03 11:19:50 +0900

など。File::Stat の詳細は、 https://docs.ruby-lang.org/ja/latest/class/File=3a=3aStat.html

File::Statクラスのメソッド

  • Unix/Linuxのタイプスタンプには3種類ある

    • atime … 最終アクセス時刻 (access time)
    • mtime … 最終変更時刻 (modify time)
    • ctime … 最終ステータス変更時刻 (change time)
  • 日付の取得

require 'date'
day = Date.today
 
puts day
#=> 2016-09-09
  • ファイルの所有ユーザ、グループを調べる ソース
require 'etc'

path = '/'
user = Etc.getpwuid(File.stat(path).uid).name
group = Etc.getgrgid(File.stat(path).gid).name
puts "#{user}:#{group} #{path}"``` #=> root:root /

を流用して

require 'etc'

user = Etc.getpwuid(File.stat("hi.rb").uid).name
group = Etc.getgrgid(File.stat("hi.rb").gid).name

puts "#{user}:#{group}"
  • モジュールEtc << etcライブラリ 

  • ハードリンク:そのファイルを開けるリンクを持つファイル名。どのファイル名からも一つのファイルにアクセスしている。全てのファイル名(リンク)が消去されて初めてファイルが消去される。

  • パーミッション情報の取得

stat = File.stat('/usr/bin/ruby').mode #=>33188
puts "0%o" % stat.mode # パーミッション #=>0100644
printf "%o\n", stat.mode
  • lstatはシンボリックリンクそのもののファイル情報を取得
  • statはシンボリックリンクのリンク先のファイル情報を取得

  • パーミッションのはじめの2桁はファイルの種類 04 : ディレクトリ(=d) / 10 : ファイル (= -) / 12 : シンボリックリンク (= l)

  • 3桁目の特殊権限

    • 0:特殊権限無し
    • 1:スティッキービット、othersのwの代わりにt/Tが立つ othersはディレクトリ内のファイル名の変更、削除ができない
    • 2:SGID(SetGroupID), xにs/Sが立つ / 4:SUID(SetUserID),xにs/Sが立つ. 所有者あるいはグループメンバー以外が実行しても所有やあるいはグループメンバーが実行したことになる。