my vimrc

my vimrc

I want to recording my vimrc here.
I don't want to add comments.

I would like to update my vimrc!

" Configuration file for vim
set modelines=0     " CVE-2007-2438

" Normally we use vim-extensions. If you want true vi-compatibility
" remove change the following statements
set nocompatible    " Use Vim defaults instead of 100% vi compatibility
set backspace=2     " more powerful backspacing

" Don't write backup file if vim is being called by "crontab -e"
au BufWrite /private/tmp/crontab.* set nowritebackup nobackup
" Don't write backup file if vim is being called by "chpass"
au BufWrite /private/etc/pw.* set nowritebackup nobackup

" Basic settings

" タイトルをバッファ名に変更しない
set notitle
set shortmess+=I

" Too fast connect to the tarminal
set ttyfast

" Use 256 colors at the tarminal
set t_Co=256

if has ("viminfo")
  " フォールド設定(未使用)
  " set foldmethod=indent
  set foldmethod=manual
  " set foldopen=all
  " set foldclose=all
endif

" 複数ファイルの編集を可能にする
set hidden

" 内容が変更されたら自動的に再読み込み
set autoread

" Swapを作るまでの時間ms
set updatetime=0

" Unicodeで行末が変になる問題を解決
set ambiwidth=double

" カーソルを常に画面の中央に。
set scrolloff=1000

" C-vの矩形選択で行末より後ろもカーソルを置ける
set virtualedit=block

" コマンド、検索パターンを50まで保存
set history=100

" ------ SEARCH -------
" インクリメンタルサーチを有効に
set incsearch

" 大文字小文字を区別しない
set ignorecase

" 大文字で検索されたら対象を大文字限定にする
set smartcase

" 行末まで検索したら行頭に戻る
set wrapscan

" ----- Format -----
" 自動インデントを有効に
set smartindent
set autoindent

" フォーマット揃えをコメント以外有効にする
set formatoptions-=c

" 括弧の対応をハイライト
set showmatch

" ターミナルの上から貼り付けを許可
" set paste

set shiftwidth=4
set softtabstop=4
set expandtab
set autoindent
set smartindent

augroup fileTypeIndent
  autocmd!
  autocmd BufNewFile,BufRead *.py setlocal tabstop=4 softtabstop=4 shiftwidth=4
  autocmd BufNewFile,BufRead *.html setlocal tabstop=4 softtabstop=4 shiftwidth=4
  autocmd BufNewFile,BufRead *.rb setlocal tabstop=2 softtabstop=2 shiftwidth=2
  autocmd BufNewFile,BufRead *.erb setlocal tabstop=2 softtabstop=2 shiftwidth=2
augroup END

" ----- Look&Feel -----
" TAB可視化
set list
set listchars=tab:>_,trail:-,eol:$
" extends:>>,precedes:<<,nb:%,

" 検索結果をハイライト
set hlsearch

" ルーラー、番号
set ruler
set number

" コマンドラインの高さ
set cmdheight=2

" カーソルラインを表示する
"set cursorline

" ウインドウタイトルを設定する
set title

"自動文字数カウント
augroup WordCount
    autocmd!
    autocmd BufWinEnter,InsertLeave,CursorHold * call WordCount('char')
augroup END
let s:WordCountStr = ''
let s:WordCountDict = {'word': 2, 'char': 3, 'byte': 4}
function! WordCount(...)
    if a:0 == 0
        return s:WordCountStr
    endif
    let cidx = 3
    silent! let cidx = s:WordCountDict[a:1]
    let s:WordCountStr = ''
    let s:saved_status = v:statusmsg
    exec "silent normal! g\<c-g>"
    if v:statusmsg !~ '^--'
        let str = ''
        silent! let str = split(v:statusmsg, ';')[cidx]
        let cur = str2nr(matchstr(str, '\d\+'))
        let end = str2nr(matchstr(str, '\d\+\s*$'))
        if a:1 == 'char'
            " ここで(改行コード数*改行コードサイズ)を'g<C-g>'の文字数から引く
            let cr = &ff == 'dos' ? 2 : 1
            let cur -= cr * (line('.') - 1)
            let end -= cr * line('$')
        endif
        let s:WordCountStr = printf('%d/%d', cur, end)
    endif
    let v:statusmsg = s:saved_status
    return s:WordCountStr
endfunction


" ステータスラインにコマンドを表示
set showcmd
" ステータスラインを常に表示
set laststatus=2
" ファイルナンバー表示
set statusline=[%n]
" ホスト名表示
set statusline+=%{matchstr(hostname(),'__w__+')}@
" ファイル名表示
set statusline+=%<%F
" 変更チェックの表示
set statusline+=%m
" 読み込み専用かどうか表示
set statusline+=%r
" ヘルプページなら[HELP]と表示
set statusline+=%h
" プレビューウィンドウなら[Preview]と表示
set statusline+=%w
" ファイルフォーマット表示
set statusline+=[%{&fileformat}]
" 文字コード表示
set statusline+=[%{has('multi_byte')&&\&fileencoding!=''?&fileencoding:&encoding}]
" ファイルタイプ表示
set statusline+=%y
" ここからツールバー右側
set statusline+=%=
" skk.vimの状態
set statusline+=%{exists('*SkkGetModeStr')?SkkGetModeStr():''}
" 文字バイト数/カラム番号
set statusline+=[%{col('.')-1}=ASCII=%B,HEX=%c
" 現在文字列/全体列表示
set statusline+=[C=%c/%{col('$')-1}]
" 現在文字行/全体文字行
set statusline+=[L=%l/%L]
" 現在のファイルの文字数をカウント
set statusline+=[WC=%{exists('*WordCount')?WordCount():[]}]
" 現在行が全体行の何%目か表示
set statusline+=[%p%%]

"-------エンコード------
"エンコード設定
if has('unix')
    set fileformat=unix
    set fileformats=unix,dos,mac
    set fileencoding=utf-8
    set fileencodings=utf-8,iso-2022-jp,cp932,euc-jp
    set termencoding=
elseif has('win32')
    set fileformat=dos
    set fileformats=dos,unix,mac
    set fileencoding=utf-8
    set fileencodings=iso-2022-jp,utf-8,euc-jp,cp932
    set termencoding=
endif

"ファイルタイプに応じて挙動,色を変える
syntax on
filetype plugin on
filetype indent on

" ----- key setting -----
" nmap <UP> k
" nmap <DOWN> j
" vmap <UP> k
" vmap <DOWN> j

" ほかのvimにviminfoを送る
" http://nanasi.jp/articles/howto/editing/rviminfo.html
nmap ,vw :vw<CR>
nmap ,vr :vr<CR>

" 保存
" map jj :w<CR>

" ESC
inoremap jj <ESC>

" 括弧を補完
inoremap ( ()<left>
inoremap [ []<left>
inoremap { {}<left>
inoremap < <><left>

" 挿入モードでのカーソル移動
inoremap <C-j> <Down>
inoremap <C-k> <UP>
inoremap <C-h> <Left>
inoremap <C-l> <Right>

" シングルコーテーション補完
inoremap ' '' <left>

" yanktmpの設定
" vim to vim でコピペ出きるようになる。
" map <silent> sy :call YanktmpYank()<CR>
" map <silent> sp :call YanktmpPaste_p()<CR>
" map <silent> sP :call YanktmpPaste_P()<CR>
" if has("win32")
"       let g:yanktmp_file = TEMP. '/vimyanktmp'
" end

たのしいRuby 読書memo 1.1

たのしいRuby の備忘録

www.amazon.co.jp

1.1 Ruby の実行方法

Ruby を実行するには、Rubyコマンドを使います。
ユーザのホームディレクトリにhello.rbというRubyのプログラムがあった場合、以下のように実行します。

$ ruby hello.rb

これだけです。
hello.rb
の中身は今は特に気にしなくて良いです。

ついでに、irb も押さえておきます。
irb とは、 Interactive Rubyの略です。
ここに書いています。

library irb (Ruby 2.4.0)

どこの場所にいても、irb で起動します。
大きなプログラムの実行にはあまり向いていないです。
小さなプログラムをちょっと試すのに良いです。

ここは以上です。

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章 ネットワーク・セキュリティをアップします。頑張りまっしょい。