tmux memo

tmux memo

Boot tmux

$ tmux

Prefix key (Default)

C-b

Window customize short cut

key sub command meaning
c new window open new window
n next-window move next window
p previous-window move previous window
, rename-window rename window
0-9 select-window move to 0-9 window number
l last-window move to last window
w choose-window display the window list then select one
& kill-window kill the present window

Pane operation key (Push below keys after prefix key)

key sub command meaning
split-window split window up/down
% split-window -h split window left/right
x kill-pane delete present pain
q display-panes display pain number
o select-pane -t :.+ move next pain
; last-pane move last pain
cursor select-pain -[U|D|L|R] move [above|below|left|light] pain
{ swap-pain -U swap pane
} swap-pain -D swap pane
C-(cursor) resize-pane -[U|D|L|R] change pane size

How to use the Rails API

目的

  • Rails API の勉強
  • 備忘録
  • 本当は API Client を Ruby で作ってみたかった

Vagrant up

環境をまっさらに戻せるように Vagrant up で作っていく。
Vagrant up が出来る環境を作るのは、機種依存もあるので、割愛します。

とはいえ参考情報として、私の環境を晒すと、、、

$ cat /etc/issue
Ubuntu 14.04.5 LTS \n \l

$ uname -a
Linux takashi-desktop 3.13.0-123-generic #172-Ubuntu SMP Mon Jun 26 18:04:35 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ vagrant -v
Vagrant 1.9.5

$ git --version
git version 2.13.0

$ VBoxManage -v
5.1.22r115126

立ち上げよう

参考

app.vagrantup.com

vagrant init ubuntu/xenial64

出来上がった、 Vagrantfile を編集して、 public network が使えるようにしよう。
下記一文をコメントイン

config.vm.network "public_network"

で、起動

vagrant up

Ruby をインストール

Ruby をインストールしていく

ホストにログイン

vagrant ssh

しなくてもいいが、バージョン確認

ubuntu@ubuntu-xenial:~$ cat /etc/issue
Ubuntu 16.04.3 LTS \n \l

ubuntu@ubuntu-xenial:~$ git --version
git version 2.7.4
ubuntu@ubuntu-xenial:~$ 
# Fix バージョンぽい

Git 脆弱性対応情報
USN-3387-1: Git vulnerability | Ubuntu

rbenv をインストール

ここを参考

https://github.com/rbenv/rbenv#installation

ubuntu@ubuntu-xenial:~$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
ubuntu@ubuntu-xenial:~$ cd ~/.rbenv && src/configure && make -C src
ubuntu@ubuntu-xenial:~/.rbenv$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
ubuntu@ubuntu-xenial:~/.rbenv$ source ~/.bash_profile 
ubuntu@ubuntu-xenial:~/.rbenv$ ~/.rbenv/bin/rbenv init
# Load rbenv automatically by appending
# the following to ~/.bash_profile:

eval "$(rbenv init -)"

ubuntu@ubuntu-xenial:~/.rbenv$ 
ubuntu@ubuntu-xenial:~/.rbenv$ type rbenv
rbenv is /home/ubuntu/.rbenv/bin/rbenv
ubuntu@ubuntu-xenial:~/.rbenv$ 

ruby-build をインストール

ubuntu@ubuntu-xenial:~/.rbenv$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
ubuntu@ubuntu-xenial:~/.rbenv$ rbenv 
rbenv 1.1.1-2-g615f844
Usage: rbenv <command> [<args>]

Some useful rbenv commands are:
   commands    List all available rbenv commands
   local       Set or show the local application-specific Ruby version
   global      Set or show the global Ruby version
   shell       Set or show the shell-specific Ruby version
   install     Install a Ruby version using ruby-build
   uninstall   Uninstall a specific Ruby version
   rehash      Rehash rbenv shims (run this after installing executables)
   version     Show the current Ruby version and its origin
   versions    List all Ruby versions available to rbenv
   which       Display the full path to an executable
   whence      List all Ruby versions that contain the given executable

See `rbenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/rbenv/rbenv#readme
ubuntu@ubuntu-xenial:~/.rbenv$ 

これで、rbenv install コマンドが使えるようになった。

Ruby 2.3.1 をインストール

ubuntu@ubuntu-xenial:~/.rbenv$ rbenv install -l | grep 2.3.1
  2.3.1
ubuntu@ubuntu-xenial:~/.rbenv$ rbenv install 2.3.1
Downloading ruby-2.3.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.bz2
Installing ruby-2.3.1...

BUILD FAILED (Ubuntu 16.04 using ruby-build 20170726-2-g254728e)

Inspect or clean up the working tree at /tmp/ruby-build.20170821144450.9867
Results logged to /tmp/ruby-build.20170821144450.9867.log

Last 10 log lines:
The Ruby openssl extension was not compiled.
The Ruby readline extension was not compiled.
The Ruby zlib extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `apt-get install -y libssl-dev libreadline-dev zlib1g-dev` to fetch missing dependencies.

Configure options used:
  --prefix=/home/ubuntu/.rbenv/versions/2.3.1
  LDFLAGS=-L/home/ubuntu/.rbenv/versions/2.3.1/lib 
  CPPFLAGS=-I/home/ubuntu/.rbenv/versions/2.3.1/include 
ubuntu@ubuntu-xenial:~/.rbenv$ 

# error が出てビルドが止まった。
# Try running を実施してみる。

ubuntu@ubuntu-xenial:~/.rbenv$ sudo apt-get install -y libssl-dev libreadline-dev zlib1g-dev
ubuntu@ubuntu-xenial:~/.rbenv$ rbenv install 2.3.1
Downloading ruby-2.3.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.bz2
Installing ruby-2.3.1...
Installed ruby-2.3.1 to /home/ubuntu/.rbenv/versions/2.3.1

ubuntu@ubuntu-xenial:~/.rbenv$ 
ubuntu@ubuntu-xenial:~/.rbenv$ ruby -v
The program 'ruby' is currently not installed. You can install it by typing:
sudo apt install ruby
ubuntu@ubuntu-xenial:~/.rbenv$ rbenv which ruby
/home/ubuntu/.rbenv/versions/2.3.1/bin/ruby
ubuntu@ubuntu-xenial:~/.rbenv$ vim ~/.bash_profile 
ubuntu@ubuntu-xenial:~$ cat ~/.bash_profile 
ruby="$HOME/.rbenv/versions/2.3.1/bin/"
export PATH="$HOME/.rbenv/bin:${ruby}:$PATH"
ubuntu@ubuntu-xenial:~$ 
ubuntu@ubuntu-xenial:~/.rbenv$ source ~/.bash_profile
ubuntu@ubuntu-xenial:~$ echo $PATH
/home/ubuntu/.rbenv/bin:/home/ubuntu/.rbenv/versions/2.3.1/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ubuntu@ubuntu-xenial:~$ 
ubuntu@ubuntu-xenial:~$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
ubuntu@ubuntu-xenial:~$ 

あまりイケてないけど、Ruby が使えるようになった。

RailsAPI モードで動かす

Rails をインストールして、API モードでアプリを作る。

インストール

gem update --system
gem install rails

これで、Rails のインストール完了

API モードでアプリケーションを作る

ubuntu@ubuntu-xenial:~$ rails new railsapimode --api
...
checking for sqlite3.h... no
sqlite3.h is missing. Try 'brew install sqlite3',
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
and check your shared library search path (the
location where your sqlite3 shared library is located).
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

どうやら、sqlite3.h が無い様子。
書いてあるとおり、コマンドを実行する。

ubuntu@ubuntu-xenial:~$ sudo apt-get install libsqlite3-dev
ubuntu@ubuntu-xenial:~$ rails new railsapimode --api
ubuntu@ubuntu-xenial:~$ rails -v
Rails 5.1.3
ubuntu@ubuntu-xenial:~$ 

上手くインストールできたようだ。

API の作成

ubuntu@ubuntu-xenial:~$ cd railsapimode/
ubuntu@ubuntu-xenial:~/railsapimode$ rails g scaffold Users name:string age:integer org:string sex:string
Running via Spring preloader in process 24106
[WARNING] The model name 'Users' was recognized as a plural, using the singular 'User' instead. Override with --force-plural or setup custom inflection rules for this noun before running the generator.
      invoke  active_record
      create    db/migrate/20170821162126_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      invoke  resource_route
       route    resources :users
      invoke  scaffold_controller
      create    app/controllers/users_controller.rb
      invoke    test_unit
      create      test/controllers/users_controller_test.rb
ubuntu@ubuntu-xenial:~/railsapimode$ 

作れた。

users_controller.rb を確認する

ubuntu@ubuntu-xenial:~/railsapimode$ cat app/controllers/users_controller.rb 
class UsersController < ApplicationController
  before_action :set_user, only: [:show, :update, :destroy]

  # GET /users
  def index
    @users = User.all

    render json: @users
  end

  # GET /users/1
  def show
    render json: @user
  end

  # POST /users
  def create
    @user = User.new(user_params)

    if @user.save
      render json: @user, status: :created, location: @user
    else
      render json: @user.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /users/1
  def update
    if @user.update(user_params)
      render json: @user
    else
      render json: @user.errors, status: :unprocessable_entity
    end
  end

  # DELETE /users/1
  def destroy
    @user.destroy
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_user
      @user = User.find(params[:id])
    end

    # Only allow a trusted parameter "white list" through.
    def user_params
      params.require(:user).permit(:name, :age, :org, :sex)
    end
end
ubuntu@ubuntu-xenial:~/railsapimode$ 

見てわかるとおり、GET や POST など、メソッドおよびアクセスするときの解説付きて展開される。

seed ファイルに、サンプルデータを入れる

ubuntu@ubuntu-xenial:~/railsapimode$ vim db/seeds.rb 
ubuntu@ubuntu-xenial:~/railsapimode$ cat db/seeds.rb 
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
#
# Examples:
#
#   movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
#   Character.create(name: 'Luke', movie: movies.first)
User.create(name: 'user1', age: 21, org: 'section 1', sex: 'man')
User.create(name: 'user2', age: 22, org: 'section 2', sex: 'man')
User.create(name: 'user3', age: 23, org: 'section 3', sex: 'woman')
User.create(name: 'user4', age: 21, org: 'section 1', sex: 'woman')

ubuntu@ubuntu-xenial:~/railsapimode$ 

migrate とか

rails db:migrate
rails db:seed
rails s

curl で動作確認

別端末を起動して、vagrant sshで中に入る。

curl でテスト。

# User 一覧の取得
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type' http://localhost:3000/users -X GET -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /users HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< ETag: W/"718134f3ca6a612c64c9c16753883eb6"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: 8f0511f4-f726-44d6-a993-0d0765bd5d71
< X-Runtime: 0.263571
< Transfer-Encoding: chunked
< 
* Connection #0 to host localhost left intact
[{"id":1,"name":"user1","age":21,"org":"section 1","sex":"man","created_at":"2017-08-21T16:27:44.054Z","updated_at":"2017-08-21T16:27:44.054Z"},{"id":2,"name":"user2","age":22,"org":"section 2","sex":"man","created_at":"2017-08-21T16:27:44.061Z","updated_at":"2017-08-21T16:27:44.061Z"},{"id":3,"name":"user3","age":23,"org":"section 3","sex":"woman","created_at":"2017-08-21T16:27:44.065Z","updated_at":"2017-08-21T16:27:44.065Z"},{"id":4,"name":"user4","age":21,"org":"section 1","sex":"woman","created_at":"2017-08-21T16:27:44.070Z","updated_at":"2017-08-21T16:27:44.070Z"}]

ubuntu@ubuntu-xenial:~$ 

# User の情報を取得
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type' http://localhost:3000/users/1 -X GET -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /users/1 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< ETag: W/"bfda4451a19a000f8bd9e150b9d23aa1"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: 9e51b1e8-5ba7-4b81-a8c3-761c94dd41f8
< X-Runtime: 0.015374
< Transfer-Encoding: chunked
< 
* Connection #0 to host localhost left intact
{"id":1,"name":"user1","age":21,"org":"section 1","sex":"man","created_at":"2017-08-21T16:27:44.054Z","updated_at":"2017-08-21T16:27:44.054Z"}

ubuntu@ubuntu-xenial:~$ 

# User を作成
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type: application/json' -d '{ "user" : { "name": "user5", "age":25, "org":"section2", "sex":"woman" } }' http://localhost:3000/users -X POST -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST /users HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 75
> 
* upload completely sent off: 75 out of 75 bytes
< HTTP/1.1 201 Created
< Location: http://localhost:3000/users/5
< Content-Type: application/json; charset=utf-8
< ETag: W/"e8248c5cbf259acf172667196f403545"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: 33be92f3-532d-40f2-84a8-ceb5c7e39467
< X-Runtime: 0.017082
< Transfer-Encoding: chunked
< 
* Connection #0 to host localhost left intact
{"id":5,"name":"user5","age":25,"org":"section2","sex":"woman","created_at":"2017-08-21T16:40:20.840Z","updated_at":"2017-08-21T16:40:20.840Z"}

ubuntu@ubuntu-xenial:~$ 

# User を更新
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type: application/json' -d '{ "user" : { "org":"section 4" } }' http://localhost:3000/users/5 -X PUT -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> PUT /users/5 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 34
> 
* upload completely sent off: 34 out of 34 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< ETag: W/"3d2c91c68c4e49004e3cbb79f62d2dea"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: 576329f0-7792-402c-a950-5de647ee22a0
< X-Runtime: 0.011775
< Transfer-Encoding: chunked
< 
* Connection #0 to host localhost left intact
{"id":5,"org":"section 4","name":"user5","age":25,"sex":"woman","created_at":"2017-08-21T16:40:20.840Z","updated_at":"2017-08-21T16:43:29.569Z"}

ubuntu@ubuntu-xenial:~$ 

# User を削除
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type: application/json' http://localhost:3000/users/5 -X DELETE -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> DELETE /users/5 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Type: application/json
> 
< HTTP/1.1 204 No Content
< Cache-Control: no-cache
< X-Request-Id: 3b51886b-3d78-40d4-8d0e-b7eb676259e2
< X-Runtime: 0.015196
< 
* Connection #0 to host localhost left intact


ubuntu@ubuntu-xenial:~$ 

# 存在しないUserを取得
ubuntu@ubuntu-xenial:~$ curl -sv -H 'Content-Type: application/json' http://localhost:3000/users/0 -X GET -w '\n\n'
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /users/0 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Type: application/json
> 
< HTTP/1.1 404 Not Found
< Content-Type: application/json; charset=UTF-8
< X-Request-Id: b1d90e0b-61e2-4e14-827a-aa3fc6dc4d76
< X-Runtime: 0.037391
< Content-Length: 10812
< 
{"status":404,"error":"Not Found"
...



次回は、このAPI modeを利用して、API Clientを作ってみたいと思います。
(基礎すっ飛ばしているから、もう一度復習しよう)

以上。

たのしいRuby で Ruby の学習 第1部

たのしいRuby の力を借りて Ruby を学習していく

実際の本は、Kindle版を買いました。
この連載?は、ツッコミ等々歓迎です。かなり端折る場合も有りますが、ご了承下さい。(省略部分を知りたい方は、購入して下さい。)

https://www.amazon.co.jp/dp/4797386290www.amazon.co.jp

環境

$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]

第1章 はじめてのRuby

さくっと流していければいいかな。

Rubyの実行方法

ruby コマンドを使う

$ ruby <program name>

## 書いたコードの確認
$ cat helloruby.rb 
print("Hello, Ruby.\n")

## 実行
$ ruby helloruby.rb 
Hello, Ruby.

irb を使う

irbコマンドは、rubyコマンドと同様にコンソールから実行する。ただし、プログラムを書いたファイルは指定しない。

irb実行例

$ irb
irb(main):001:0> 

ここに、先ほど作ったプログラムの内容をそのまま入力し、[Enter]キーを押すとその場で実行される。

irb(main):001:0> print("Hello, Ruby.\n")
Hello, Ruby.
=> nil
irb(main):002:0> 

終了するときは、exitCtrl-d (CTRL + d) です。

改行文字と[\]

改行文字 \n
エスケープ文字 \
つまり、\ はエスケープ文字と呼ばれ、\n\ そのものなど、特殊文字の特殊効果をエスケープ(回避)できるわけです。

[‘’] と [“”]

シングルクォート [‘’]
ダブルクォート [“”]
これ、動きが違います。
シングルクォートで囲まれると、囲まれた中身?にある特殊な文字列や変数の展開などは行われません。

$ irb
# ダブルクォートで囲まれているため、\n が効力を発揮して、改行されている。
irb(main):001:0> print("hello, \nRuby")
hello, 
Ruby=> nil

# シングルクォートで囲まれているため、\n の効力が消え、\n そのものも文字列として扱われる。
irb(main):002:0> print('hello, \nRuby')
hello, \nRuby=> nil
irb(main):003:0> 

メソッドの呼び出し

print メソッドを例に出す。
メソッドを呼び出すときは、()を省略できる。

$ irb
irb(main):001:0> print("hello\n")
hello
=> nil
irb(main):002:0> print "hello\n"
hello
=> nil
irb(main):003:0> 

同じ結果になりました。

puts メソッド

よく使われると思います。
表示する文字列の最後で必ず改行します。

$ irb
# 改行 \n を行末に書いてないけれど、改行されている。
irb(main):001:0> puts "hello, Ruby."
hello, Ruby.
=> nil

# 引数を2つ渡した場合、それぞれの文字列の最後で改行される。
irb(main):002:0> puts "hello, ", "Ruby."
hello, 
Ruby.
=> nil
irb(main):003:0> 

p メソッド

オブジェクトの内容を表示するときに便利。
例えば、数値か文字列かを表示分けしてくれる。

$ irb
# 文字列
irb(main):001:0> puts "100"
100
=> nil

# 数値
irb(main):002:0> puts 100
100
=> nil

# 文字列
irb(main):003:0> p "100"
"100"
=> "100"

# 数値
irb(main):004:0> p 100
100
=> 100
irb(main):005:0> 

p の時は、文字列を出力するときに"“で囲われている事が確認できる。
原則として、pメソッドはプログラムを書いている人の為のメソッド。

日本語の表示

日本語を表示したければ、文字列を""で囲ってしまうだけでいい。
しかし、文字コードに気をつけよう。

Ruby では、# encoding: 文字コード というコメントを1行目に記述することで文字コードを指定します。
このコメントのことを マジックコメント と言います。
環境に合わせて適切なものを選ぼう。

プラットフォーム 文字コードエンコーディング)名
Windows Shift_JIS (又は、(Windows-31J)
Mac OS X (macOS) UTF-8
Unix UTF-8, EUC-JP など

マジックコメントがない場合は、UTF-8と仮定される
実行時に出力用の文字コードを指定することも出来る。

$ ruby -E UTF-8 ファイル名
$ irb -E UTF-8

と指定することで出来る。

数値の表示と計算

表現方法

Ruby で整数オブジェクトを表現するのは簡単。
数字をそのまま書くだけ。

1

と書けば、1の値の整数(Fixnum)オブジェクトになる。

100

と書けば、100の値の整数オブジェクトに

3.1415

と書けば、浮動小数点(Float)オブジェクトになる

数値を表示するには

puts(10)
puts 100

でOK

$ irb
irb(main):001:0> puts(10)
10
=> nil
irb(main):002:0> puts 100
100
=> nil
irb(main):003:0> 

四則演算やその他の演算

$ irb --simple-prompt
>> 1 + 1
=> 2
>> 2 - 3
=> -1
>> 5 * 10
=> 50
>> 100 / 5
=> 20

# 99 を 5 で割った余り
>> 99 % 5
=> 4
>> 20 + 80 / 4
=> 40
>> (20 + 80) / 4
=> 25

# 3^3 のこと
>> 3 ** 3
=> 27
>> 

変数

オブジェクトに名札をつけるようなイメージ
オブジェクトに名札をつけるには

変数名 = オブジェクト

alphabet = "abcdefg"
num = 10
age = 22
name = 'TAKA'

実践例
直方体の表面積と体積を求めるプログラムを見てみよう
area_volume.rb

# encoding: UTF-8
x = 10
y = 20
z = 30
area = (x*y + y*z + z*x) * 2
volume = x * y * z
print "表面積=", area, "\n"
print "体積=", volume, "\n"

と表現できる。

もし、変数を使わなかった場合、値を変更するのが一苦労となる。
上記例の場合は、まだ良いが、量が増えるに連れミスの元となる。

また、変数名はある程度意味のわかる単語にしましょう。
例えば、上記x,y,z が、foo,bar,baz だったとすると、ぱっと見て意味のわかりづらいプログラムになります。

area = (foo*bar + bar*baz + baz*foo) * 2

意味がわかりませんね。

少しprintメソッドを見てみよう

print "表面積=", area, "\n"

これは、printメソッドに"表面積=", area, "\n"の3つの引数を順番に実行しています。
area は、前段の area 変数の計算結果の展開がなされます。
前半の文字列と、後半の改行コードと合わせることで、結果が出力されます。
上記プログラムの出力

$ ruby area_volume.rb 
表面積=2200
体積=6000

別の書き方もあります。
print "表面積=#{area}\n"
こうすると、1つの""で全てを満たして出力してくれます。

更に、putsメソッドを使うと、改行コードも必要なくなるので、
puts "表面積=#{area}"
でOKです。スッキリしましたね。

コメントを書く

コメントを表す記号は# です。
# 以降の当該行の文字列は全てコメントになります。
また、以下の場合も、コメントとみなされます。

=begin
ここ
何行でもOK
=end

上記のような記載をすると、範囲が広い場合に有効だと思います。
しかし、個人的にはコメントを外して適用したいという時に使えないので、微妙だと考えていたりします。

制御構造

  • 逐次処理
  • 条件判断
  • 繰り返し
  • 例外処理

条件判断:if - then - end

いきなり例

if 条件 (then)
  処理
end

then は省略できる。

条件式の例

$ irb --simple-prompt
>> p (1 == 1)
true
=> true
>> p (1 == 2)
false
=> false
>> p (1 < 2)
true
=> true
>> p (1 < 0)
false
=> false
>> p (1 <= 1)
true
=> true
>> p (1 <= 0)
false
=> false
>> p (2 > 1)
true
=> true
>> p (1 >= 1)
true
=> true
>> p ("a" == "a")
true
=> true
>> p ("a" == "b")
false
=> false
>> p ("a" != "b")
true
=> true
>> p ("a" != "a")
false
=> false

基本的には、上記のような記号で判定できます。
!= は not equal を表します。

サンプル

# coding: UTF-8
# ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]

a = 20
if a >= 10 then
  puts "a:#{a} is bigger than 10"
end

if a <= 9 then
  puts "a:#{a} is smaller than 9"
end

#output
#=> a:20 is bigger than 10

else を使うと上記サンプルを少しシンプルに出来ます。
then が省略できると言うことなので、それも盛り込んでみます。

サンプルプログラム
big_small_else.rb

# coding: UTF-8
# ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]

a = 20
if a >= 10
  puts "a:#{a} is bigger than equal 10"
else
  puts "a:#{a} is smaller than 9"
end

#output
#=> a:20 is bigger than equal 10

繰り返し

同じことを繰り返したいときに使う。

while 文

while 繰り返し続ける条件 do
  繰り返したい処理
end

例:1から10までの数を順番に表示する

i = 1
while i <= 10 do
  puts i
  i = i + 1
end

times メソッド

繰り返しの回数が決まっている時、これを使うとシンプルになる。

繰り返す回数.times do
  処理
end

例:hello と10回表示する

>> 10.times do
?>   puts "hello"
>> end
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
=> 10
>> 

timesメソッドはイテレータと呼ばれるメソッドです。
イテレータ(iterator)はRubyの特徴的な機能らしいです。
繰り返す(iterate)もの(-or)という意味を持っています。
その名の通り、繰り返しを行うためのメソッドです。

times以外にもRubyは数多くのイテレータを提供している。


以上で第1章は終わりです。ありがとうございました。

九九のプログラムを書いてみよう
multiplication_table.rb

# coding: UTF-8
# ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]

i = 1
9.times do
  j = 1
  9.times do
    x = i * j
    puts "#{i} x #{j} = #{x}"
    j = j + 1
  end
  i = i + 1
end

#=> output
$ ruby multiplication_table.rb 
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
1 x 4 = 4
1 x 5 = 5
1 x 6 = 6
1 x 7 = 7
1 x 8 = 8
1 x 9 = 9
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
4 x 1 = 4
4 x 2 = 8
4 x 3 = 12
4 x 4 = 16
4 x 5 = 20
4 x 6 = 24
4 x 7 = 28
4 x 8 = 32
4 x 9 = 36
5 x 1 = 5
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25
5 x 6 = 30
5 x 7 = 35
5 x 8 = 40
5 x 9 = 45
6 x 1 = 6
6 x 2 = 12
6 x 3 = 18
6 x 4 = 24
6 x 5 = 30
6 x 6 = 36
6 x 7 = 42
6 x 8 = 48
6 x 9 = 54
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
8 x 1 = 8
8 x 2 = 16
8 x 3 = 24
8 x 4 = 32
8 x 5 = 40
8 x 6 = 48
8 x 7 = 56
8 x 8 = 64
8 x 9 = 72
9 x 1 = 9
9 x 2 = 18
9 x 3 = 27
9 x 4 = 36
9 x 5 = 45
9 x 6 = 54
9 x 7 = 63
9 x 8 = 72
9 x 9 = 81
$

はじめてUNIXで仕事をする人が読む本 の備忘録 19 ネットワーク・セキュリティ

お世話になった本

この連載ブログを書くにあたり、お世話になった本がこちら。LPICと被っているところもありますが、実務での使い方なんかも扱っており、良書だと思います。

第3部 ネットワーク技術

第19章 ネットワーク・セキュリティ

セキュリティについては、深すぎて個々人でここの仕組みを調べてもらうしか無いが、とりあえず見ていく。

ネットワーク上の攻撃

代表的な攻撃例

  • 脆弱性攻撃
    • ソフトウェアやシステムの脆弱性を狙い、想定外の入力を与えてシステムを破壊したり、DBから情報を抜き取ったりする
    • 本来は許可されていない権限を外部から取得したり、操作が可能なシステムの「穴」を狙う
  • コンピュータ・ウィルス / ネットワークワーム等
    • 広義では、悪意を持ってコンピュータやシステムに被害をもたらすことを目的としてさくせされたプログラムを、一般にコンピュータウィルスと呼ぶ
    • 狭義では、プログラムの一部を書き換えて自信を忍ばせ、そのプラグラムが実行された際に自信のコピーを作っていく動作をするプログラムを指すのが、コンピュータウィルスの本来の定義
    • 宿主を持たず、自信が1つのプログラムとして完結しており、主にネットワーク環境やUSBメモリ等の外部記憶装置を経由して拡散してくプログラムをネットワークワームとよぶ
    • 今では、厳密な区分はない
    • 両方の性質を兼ね備えたものもある。
  • DoS / DDoS 攻撃
    • DoS (Denial of Service) の略
    • サービス停止攻撃とも呼ぶ?
    • あるサービスに対して処理を意図的に処理を集中させることで、サービスを使用停止に追い込む攻撃
    • その攻撃を分散型にしたのが DDoS
    • DDoS (Distributed DoS) と呼ぶ
    • 詳しくは書籍やWebで
  • ブルートフォースアタック
    • 気からずく攻撃
    • 全パターン網羅攻撃とでも言うか。
    • 例えば、4桁のパスコード全パターンを試す場合、10,000 回試してみることを言う
  • ポートスキャン
    • TCP/UDP のポートは0-65535 ポートとと決まっている
    • 全てのポートに対してスキャンを行うことで開いているサービスを突き止める
    • 開いているサービスに脆弱性があれば、それをとっかかりとして、脆弱性攻撃などを行う
  • パスワードクラック
    • ブルートフォースアタックや辞書攻撃等を使ってパスワードをクラックすること
    • パスワードを何回か間違えたらロックする処理をすることも攻撃に対しての対策として有効
    • 辞書で推測可能な文字をパスワードに使わないことも有効
  • フィッシング (phishing)
    • Web サービスやSNSのメッセージを使って、一見正しそうだが全く異なったサイトのURL のリンクを踏ませることで、アカウントの情報を盗み出す手法
  • IPアドレス詐称
  • トロイの木馬
    • 普通の有用なソフトウェアと思い込ませておいて、実は中に悪意のあるソフトウェアが組み込まれたソフトウェアのこと
  • 通信内容の盗聴
    • スニッフィングともいう
    • LAN の中を流れている情報を盗聴できる。
    • 盗聴されても中身を解析されないように、暗号通信を推奨する

認証システム

認証 Authentication と 認可 Authorization がある。
認証は、各エンティティ自身が正しくそれら自身であることを確認する
認可は、各エンティティ自身がどのような権限が与えられているかを確認する
100% 安全な認証はない。

よく利用されている認証システムの例

  • パスワード認証
  • 二段階認証
    • 異なる経路による重複認証
    • ネットワーク経由と電話やFAXなど
  • 生体認証
    • 指紋・静脈・網膜パターン
  • 公開鍵認証
    • リモートログイン
    • デジタル証明書
  • 証明書認証
    • サービス
    • クライアント・端末
    • デジタル署名

また、他にもシングルサインオン(SSO)という仕組みもある。
ユーザは例えば最初に一度どこかのサイトに対してパスワード認証や証明書認証などでサインオンすれば良い。その後は明示的にサインオフするまでは他のサイトに対しても自動的にサインオン状態が引き継がれる。
ユーザにとっては嬉しい。しかし、クラッカーにとっては1つ認証情報が分かればよいだけなので、一長一短。

シングルサインオンシステムの例

  • 一般向けサービス
  • 研究・学術サイト用サービス
    • GSI (Grid Security Infrastructure)
    • 学認 (学術認証フェデレーション)

通信フィルタとファイヤウォール

ファイヤーウォールは大事。異なる複数のセキュリティポリシーを持ったネットワーク同士を接続するときには特に大事。
UNIX 機でもファイヤーウォールを構築できる。

通信フィルタを設定する際には、特定のパケットのみを通してそれ以外を全部遮断する方法と、逆に特定のパケットのみを遮断してそれ以外を全部通す方法がある。
前者のほうが比較的安全。
通信は、往復のパケットが通って初めて成立することを忘れてはいけない。
例えば、外部からのパケットを全部遮断した場合、内部から始めた通信の戻りも塞いでしまうので、通信が成立しなくなる。

通信の暗号化

通信内容が第3者に漏れないように、通信を暗号化しよう。
IPネットワークで通信内容を暗号化するには、IPsecの様にネットワーク層で行う方法、SSL/TLSのようにトランスポート層で行う方法、SSHの様にアプリケーション層で行う方法などがある。

VPN

通信を暗号化する技術を利用して、インターネット上で仮想的な専用回線を運用する技術がVPNである。
専用線を使わずとも拠点間の接続を安全に出来る。
それはまるで、LANに直接接続しているのと同じように利用できる。

ただし、スループットや遅延と言ったパフォーマンス上の制約はあるし、接続方式によっては課金対象になることもある。

UNIX でよく使われるVPN技術は、以下のようなものがある。


お疲れ様でした。これで本冊子の紹介は終了しました。また別の良い本などに出会えたら、ちょろちょろとアップしていきたと思います。
以上です。

はじめてUNIXで仕事をする人が読む本 の備忘録 18 IP関連の技術

はじめてUNIX で仕事をする人が読む本 の備忘録 18

お世話になった本

この連載ブログを書くにあたり、お世話になった本がこちら。LPICと被っているところもありますが、実務での使い方なんかも扱っており、良書だと思います。

第3部 ネットワーク技術編

第18章 IP関連の技術

IPを使用していく上での関連が深い、いくつかの技術を紹介してくれている。

名前解決

IPアドレスだけだと人間が覚えるのに限界があるため、技術が生まれた。
最初は、各端末の /etc/hosts ファイルにIPアドレスと名前の対応を作り保存することで名前解決を実施していた。
ネットワークが世界に広がっていく中で、管理しきれなくなり、DNS の概念が生まれた。

階層型の名前解決である。
www.example.co.jp で言うと
正式名称(FQDN) は、www.example.co.jp. である。
右から解説すると、
. はルートDNSサーバ。ここで各国のgTLD を名前解決している。なので、jp.を持っているDNSサーバの情報を問い合わせ元のDNSサーバに返す
jp.は日本のどこかで管理されている。そこで、co.jp.DNSサーバの情報を解決できる
co.jp.example.co.jp. を管理している。ここまで来ると結構企業の内部のDNSサーバだったりする。
example.co.jp.www.example.co.jp を知っている。なので、www.example.co.jp を名前解決し、IPアドレスを返す。
晴れて、クライアントはwww.example.co.jp. にアクセスできる。

IPアドレスの付与

これは省略

アドレス変換(NAT / NAPT / IPマスカレード)

IPアドレスは世界中でユニークでなければならない。しかし、数は有限である。そこで出てきたのが、このNAT等の技術。
IPマスカレードは、NAT/NAPT の総称でもある(はず)

トラブルシューティング

よく使うコマンド

  • ping
  • ping6
  • traceroute
  • traceroute6
  • tracepath
  • ifconfig
  • arp
  • netstat
  • dig
  • tcpdump


以上で、第18章 IP関連の技術について終わります。
次回は最終章、第19章 ネットワーク・セキュリティをアップします。頑張りまっしょい。

はじめてUNIXで仕事をする人が読む本 の備忘録 17 アプリケーションプロトコル

はじめてUNIX で仕事をする人が読む本 の備忘録 17

お世話になった本

この連載ブログを書くにあたり、お世話になった本がこちら。LPICと被っているところもありますが、実務での使い方なんかも扱っており、良書だと思います。

第3部

第17章 アプリケーションプロトコル

ネットワークアプリケーションには様々なものがある。基本的には、ネットワークを使って情報通信を行うアプリケーションは全てネットワークアプリケーションと呼ばれる。

Webアクセス(HTTP/HTTPS)

HTTP/HTTPSは主にWebアクセスに使用されるプロトコル
おそらく現在最も広く利用されている。

複数の文書間の垣根を越えて、用語などの参照関係を相互にたどることが出来るハイパーテキストと呼ばれる仕組み/考え方を元に、ネットワーク上に分散した情報相互の間に気づかれた関係を参照することを実現するプロトコルとして策定されたのが、HTTPである。
全世界的に分散した情報全体が網の目のように参照し合っている状態をWorld Wide Web (WWW)と称し、WWWのリンクをたどることに特化したUIをWWWブラウザまたは単にブラウザと呼ぶ。

URL ネットワーク上に存在するリソースの所在を表す統一的な表記
URI URLをより一般的な識別子として拡張した概念

URI には以下のような情報を含めることが出来る

  • リソース自体の場所を表す情報
  • そのリソースにアクセスするためのスキーム
  • アクセス権限を行使するための認証情報
    • ユーザ名やパスワードなど
  • アクセスする際に情報提供側で参照されるパラメータ情報
  • など

HTTPSSSLあるいはそれを拡張したTLSと呼ばれる通信の安全を確保する仕組みを利用して、HTTP通信を第三者の攻撃から守るようにしたプロトコル
HTTPSでは、通信内容を暗号化したり、改ざんを検出したり、デジタル証明書の技術を利用して通信相手であるサーバやクライアント(ブラウザ)に対する一方向あるいは双方向の認証を行うことが出来る。
一般によく利用されるのは、正式に運用されていることを保証するサーバ証明書の導入と、それを利用した暗号化通信。
証明書は、信頼できるCAが発行したものである必要がある。
現在利用されているほとんどのブラウザでは知らないCAが発行した証明書を使用している場合には、警告を出すか、通信を行わないようになっている。プライベート証明書(オレオレ証明書)を利用するなら、ユーザ側でブラウザやOSにプライベートCAを信頼できるCAとして登録する必要がある。

電子メール(SMTP/POP/IMAP)

未だに無くならない、インターネット上で古くから使われているサービスの一つ。
MTA Mail Transfer Agent でメールを転送し、
MUA Mail User Agent でメールを送受信する

SMTPはメールを送信する際に利用されるプロトコル
最初は、シンプルに英文テキストしか遅れなかった。
MIMEの登場により、多言語対応や添付ファイルが出来るようになった。

POP や、IMAP はメールを受信するときに使用するプロトコル
POPは基本的に、サーバにあるメールボックスからメールを全てダウンロードする。
IMAPは、サーバ上のメールボックス上で管理して、手元のPCからはリモートメールボックスを操作する仕組み。
端末が一つの場合は、POPでいいだろうが、複数で一つのメールアドレスを確認する場合はIMAPが便利だろう。

リモートログイン(TELNET/SSH)

リモートログインは、物理的に離れた場所からネットワーク経由でコンソール操作を行うネットワークアプリケーション。
TELNETは古いので、認証情報などを暗号化しておらず、全て平文で送られる為、現在あまり使わないことが推奨されている。しかし、地味にHTTPの接続テストとかで使えたりするので、侮れない。
どうしても、TELNETを使いたいときは、先にIPsec などで通信そのものを暗号化した上で使うとよい。

SSHは暗号化を前提としたリモートログイン用のアプリケーションプロトコルである。
パスワード認証や公開鍵認証も利用できるため、より安全に利用できる。
ポートフォワード機能もあり、特定のTCPポートの接続をリモートログイン先との間で双方向に転送することが出来る。
これを利用することで、SSHトンネルと呼ばれる簡易的なVPNが実現できる。

類似の技術に、RCP / VNC がある。

ファイル転送(FTP/rsync)

ファイル転送のプロトコル。特に、FTPTELNET と並ぶ最古のアプリケーションプロトコルの一つ。
FTP は暗号化に対応していない。IPsecなども併用しないと全て平文でネットワークを流れてしまう。
さらに、FTPでは、コントロールセッションとデータセッションの2つのセッションを利用する特殊なプロトコル

rsync は、UNIX上のファイルシステムのコピーをリモート環境に作成し、両者を同期するネットワークアプリケーションである。リモート環境への接続は、SSH などの他のプロトコルを利用するため、通信内容は暗号化される。

NFS / SMB

講義にはファイル転送の一種と言えるが、通常のファイルシステムの一部としてリモートのディスクをマウントすることを前提としたアプリケーションプロトコルである。
ユーザとしては、ネットワーク越しにファイルを転送したという意識はない。ローカル環境のファイルと同じように扱える。

NFS は古くからUNIX環境で広く使われている。SMB / CIFS は主にWindows 環境で広く利用されている。 いずれも、LAN環境で利用することが前提。

VoIP(SIP/RTP)

VoIP (Voice over IP)は、IPを使った音声通信アプリケーションプロトコル
使用しているプロトコルは、SIP / UDP / RTP が主だったところだろう。
SIPで発呼着呼を管理し、さらに、SIPサーバでDNSの仕組みを利用して電話番号から通信相手のサーバを検索できるようになっている。音声データの転送はUDPパケットにカプセル化されたRTP(Real time Transport Protocol)を使い、音声通話を実現している。

システム運用管理(DNS/DHCP/NTP/SNMP)

他にも様々なプロトコルが活躍している。
NTP は時刻を正確に合わせるために使われている。階層的にサーバ構成を構築できる。最上位のサーバは、原子時計GPS衛星からの情報を元に正確な時刻を設定している。
SNMP はネットワーク管理用のアプリケーションプロトコル。監視対象機器にSNMPエージェントを設定し、SNMP マネージャが定期的若しくはイベント発生毎にエージェントに対して状態を取得するのが基本的な仕組み。

DNS / DHCP は割愛。

Xプロトコル

X Window System は、UNIX 上で広く利用されているウインドウシステムである。ほとんどのデスクトップ環境は、X Window System 上に構築されている。
ディスプレイ、キーボード、マウスなどのポインティングデバイスを管理するのが、X Server
ここのウィンドウアプリケーションが X Client

画面上の更新はX Client から、X Server に対する描画指示として送られる。この際のX Client と X Server 間のアプリケーションプロトコルがXプロトコルである。

X Protocol はネットワーク上を流れる普通のIPプロトコルなので、X Server と X Client が同一のホスト上で動いている必要はない。

両者が別のホストで稼働している場合、
ユーザの手元のPC上でディスプレイやデバイスを管理しているのが X Serve で、
リモートホスト上で動くアプリケーションが X Client となる。

一般的な認識と立場が逆になる点は留意しておこう。


以上で、第17章 アプリケーションプロトコル を終わります。 次回は、第18章 IP関連の技術です。
全19章なので、ゴールは後もう少し。がんばっていきまっしょい

はじめてUNIXで仕事をする人が読む本 の備忘録 16 TCPとUDP

はじめてUNIX で仕事をする人が読む本 の備忘録 16

お世話になった本

この連載ブログを書くにあたり、お世話になった本がこちら。LPICと被っているところもありますが、実務での使い方なんかも扱っており、良書だと思います。

ネットワーク

第16章 TCPUDP

TCPUDPトランスポート層プロトコル

ポート番号

HTTP 80
HTTPS 443 とか有名ですよね。

UDP

UDPは単一のデータグラムを送受信する際に使用されるプロトコルである。
データの到達性などは保証しない。

TCP

TCPは連続するデータストリームの送受信をする際に使用されるプロトコル
連続性と到達性を保証する仕組みが組み込まれている。
信頼性が必要なアプリケーションにおいて使用される。

TCP のコネクション

TCPでは、まずはじめにコネクションの確率を行う。開始と終了の合図。
いわゆる、「3ウェイハンドシェイク」
終了するときは、FIN > ACK > FIN > ACK とやりとりして終わる。片方だけFINを送った状態をハーフクローズという。

TCP の通信

TCPでは切れ目のない連続したデータを扱えるが、実際のデータの送受信はIPレイヤにおいてパケット単位に分割される。これをTCPレイヤで結合し、連続するデータであるかのようにアプリケーションに提供していく。
キーワードは、シーケンス番号。これが付与されるので、パケットの順序性を保証できる。

TCP の通信の制御

基本は、データを送信して、ACKが帰ってきたら次のデータを送信する。という動き。
しかし、これでは高速にデータのやりとりが出来ない。そこで出てきた概念がウィンドサイズだ。
ある程度まとまって送信しても良いデータ量を決めておく。ACKが帰ってくる前に一気に送ってしまうのだ。
ACKの帰ってくるまでデータを送信側で保持しておくことで、再送要求に対応する。

この機能を利用して、一度に送信する量を変更させることで、輻輳制御も可能になる。

他にも一度にACKを返すほうが効率的ということで、遅延ACK等の制御もある

TCPUDP の使い分け

TCPだけで十分じゃないかという人もいるかもしれないが、リアルタイム性の要求されるパケットに再送されても意味があまりないので、その場合はUDPを使うことが多い。
例えば、音声・動画のストリーミング通信等である。
データ再送が不要で、むしろ通信の遅延のほうが問題になるようなアプリケーションの時にUDPが使われる。


以上で、第16章 TCPUDP を終わります。
次回は、第17章 アプリケーションプロトコル です。