日本語の場合、CSVのファイルエンコードをShift JISにする要件がけっこうあると思います。
RubyのCSVライブラリは、encoding
というオプションが用意されており、encoding: ’sjis’
のようにファイルエンコーディングを指定できます。
1 2 3 4 |
|
nkfコマンドを使ってファイルエンコーディングを確認します。
1 2 |
|
Shift_JISで作成されていることが確認できました。
日本語の場合、CSVのファイルエンコードをShift JISにする要件がけっこうあると思います。
RubyのCSVライブラリは、encoding
というオプションが用意されており、encoding: ’sjis’
のようにファイルエンコーディングを指定できます。
1 2 3 4 |
|
nkfコマンドを使ってファイルエンコーディングを確認します。
1 2 |
|
Shift_JISで作成されていることが確認できました。
FTPはすでにご存知のかたも多いと思います。
自分はFTPについて、「ファイル転送に使われるプロトコルであり、セキュリティが脆弱である」というくらいしか理解していなかったので詳細を把握するために調べました。
FTPとはインターネットの初期の頃から存在するプロトコルで、今でもインターネットでよく使われています。
用途としては、以下に使われます。
FTPを利用するにはユーザー名とパスワードが必要です。
ソフトを配布するための目的で使う匿名でアクセスできるAnonymous(匿名)FTPサーバーもあります。
しかし、形式上ユーザー名とパスワードは必要なので、ユーザー名にanonymousやftpを使います。パスワードは何でもよいですが、慣習としてメールアドレスを入力するようです。
FTPのプロトコルはRFC959に定義してあります。
RFC959が書かれたのが1985年なのでおよそ30年前に作られたプロトコルです。
FTPは大きくわけると、コネクションの確立とデータ転送にわけることができます。
そして、使うポートも2つが用意してあります。
20番がデータを転送するときに使うポートで、21番は認証などの接続に使うためのポートです。
FTPは アクティブモード
か パッシブモード
のいずれかで動作し、サーバーとの接続をする際にどちらかを選択します。
アクティブモードの場合、クライアントはデータ転送用のポートを用意しPORTコマンドを使って待ち受けポートをサーバーに伝えます。
サーバーはPORTコマンドを受け取ると、そのポートに対して接続を行います。
しかし、Firewallがある環境の場合、サーバーからの接続が拒否されうまくいかない場合があります。
その際はパッシブモードを使います。
パッシブモードでは、まず最初にクライアントがPASVというコマンドを使いサーバーに送信します。
そのコマンドを受け取ったサーバーは自身のIPアドレスとポート番号をクライアントに送信します。
クライアントは受け取ったIPアドレスとポート番号へコネクションを確立しにいきます。
アクティブモードはサーバーより接続を行う、パッシブモードはクライアントより接続を行うという違いがあります。
ちなみに、FTPはよく使われるプロトコルのため、PORTコマンドがFirewallを通過する際にPORTコマンドに書かれたPORTは通過できるようにしてくれるFirewallもあるとのことです。
接続ができたら、次はデータ転送を行います。
FTPにはデータタイプという考え方があって、現在は2つのモードが使われています。
アスキーモードは、必要であればデータを変換します。
例えば異なるOS間でファイルを送ると改行コードが違ったりする場合があると思いますが、アスキーモードはファイルを受け取るホストに適した改行コードにファイルを変換します。
Imageモードは一般的にバイナリモードと呼ばれます。
バイト単位でデータを転送します。
アスキーモードのようにデータの変換は行われません。
データの転送モードには、以下の3つのモードがあります。
データをそのまま転送するモードです。
データをブロックに分割して転送するモードです。
ランレングスエンコーディングを使ってデータを圧縮して転送するモードです。
FTPはセキュアなプロトコルとして設計されていません。
ユーザー名やパスワードを暗号化せずに送信する問題のほかにも数多くのセキュリティ脆弱性があげられています。
また、通信内容を暗号化できないので通信経路上でパケットキャプチャすることで盗聴することができてしまいます。
セキュアにする一般的な方法として、SSL/TLSセッション上で通信を行うようにします。
これをFTPSと言います。
また、SSHを介してファイル転送を行うSFTP、SCPを使います。
ちなみにFTPSとSFTPの違いは以下のようになります。
理解を深めるためにtelnetを使って実際にFTPサーバーと通信してみます。
実際にFTPを試してみる場合、FTPサーバーが必要です。
ロリポップ!レンタルサーバーを使えば無料でFTPサーバーが利用できます。
ちなみにtelnetでファイルの送受信はできません。
というのも、telnetでは1つのポートを使った通信しかサポートしていないからです。
FTPはデータ転送用のポートと制御用のポートの2つを利用するため、telnetでは認証しか行えません。
まずは、telnetで認証をやってみます(localhostにftpサーバーが起動しているという前提です)。
1 2 3 4 5 |
|
まず、ユーザ名を入力します。
1 2 |
|
次に、パスワードを入力します。
1 2 |
|
telnetでは他に何もできませんのでQUITします。
1 2 3 |
|
FTPでファイルの送受信を行うには、ftpコマンドを使います。
-d
オプションはデバッグモードです。
1
|
|
ユーザー名とパスワードを聞かれるので入力します。
ls
でファイルの一覧をみることができます。
1 2 3 4 5 6 7 8 9 10 |
|
get
コマンドでファイルをダウンロードできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
参考リンク
Rubyでファイルエンコーディングを確認するにはNKFモジュールを使って確認します。
http://docs.ruby-lang.org/ja/2.3.0/class/NKF.html
NKFモジュールとは、nkf(Network Kanji code conversion Filter, http://sourceforge.jp/projects/nkf/) をRubyから使うためのモジュールです。
1 2 3 4 5 |
|
このような感じでrspecでテストするときにも使えます。
1 2 3 4 5 6 |
|
wheneverを導入するためCapfile
に require "whenever/capistrano"
と定義して bundle exec cap -T
とすると以下のエラーがでた。
1
|
|
実際にvendor/bundle/ruby/2.2.0/gems/whenever-0.9.5/lib/whenever/tasks/whenever.rake
を確認してみると、たしかにそのファイルが存在しない。
wheneverのリポジトリを見てみると、シンボリックリンクがはってあった。
bundle install
したときにはシンボリックリンクがはられないようだ。
手元のRubyのバージョンは、2.2.4だった。
ruby2.3.1で実行してみると Gem::Package::PathError
が発生した。
1 2 |
|
このエラーはRuby2.3.2では直っていることが期待される。
Capfileでの指定はやめて、lib/capistrano/tasks
以下にwhenever.taskを作成した。
これでcapのタスク自体は実行できるようになった。
しかし、ruby2.3.1の環境ではbundle installがこけるのでwheneverの導入自体ができないという状況。
bundle installがこけるバグは以下のPRがでており0.9.6で修正されていた。
また、0.9.5では cap whenever:update_crontab
で instance variable @_env not defined
が発生してコマンドが正常に実行できないバグがあったが、0.9.7で修正されている。
実はこのバグは自分が踏んでおり、その修正案をPRしてCHANGELOGに名前が刻まれた。
Capistrano/sshkitを紹介します。
https://github.com/capistrano/sshkit
SSHKitはリモートサーバーに対してコマンドを実行するためのツールキットです。
CapistranoやCapistranoプラグインではSSHKitが使われています。
1
|
|
実際に使ってみて理解していきます。
使うには、sshkitをロードする必要があります。
1 2 |
|
まずはログインしてホスト名を取得してみましょう。
1 2 3 4 |
|
on
メソッドに対象のサーバーとブロックを渡します。
対象のサーバーは複数設定することも可能です。
ブロックにはサーバー上で実行するコマンドを設定します。
capture
メソッドは渡された引数をコマンドとして実行し、結果をログに出力します。
特定のユーザーでコマンドを実行する場合は、as
メソッドで指定します。
1 2 3 4 5 |
|
特定のディレクトリを指定する場合は、within
メソッドを指定します。
1 2 3 4 5 |
|
/var/log
で head -n5 messages
を実行します。
with
メソッドで環境変数を指定することができます。
1 2 3 4 5 |
|
rack_envに:test
を設定しています。
1 2 3 4 5 6 7 8 9 10 |
|
test
メソッドでファイルをチェックし、execute
メソッドでtouch
コマンドを実行しています。
ファイルをアップロードすることもできます。
1 2 3 |
|
第1引数がローカルのファイルのパス、第2引数がサーバーに配置するファイルのパスです。
また、recursive
オプションをtrueに設定することでディレクトリをアップロードすることもできます。
1 2 3 |
|
ローカルで実行することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
RakeタスクでSSHKitのDSLを使うこともできます。
この仕組みを利用してCapistranoのプラグインは作成されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
サンプルがこちらにたくさんあるので、参考になると思います。
https://github.com/capistrano/sshkit/blob/master/EXAMPLES.md