Rubyにはファイルを操作するクラスが用意されているので、それを利用すればファイルをコピーするプログラムをRubyで作成することが可能です。外部コマンドとしてLinux OSに付属するcpコマンドを利用する方法もありますが、ファイルを操作するクラスを利用してください。
今回はRubyでファイルを操作するライブラリ、FileUtilsモジュールを利用したファイルをコピーするプログラムを作る方法を紹介します。
ファイルをコピーするには
プログラムの中で特定のファイルをコピーしたい場合、どうすればよいでしょうか。もしWindowsでコピーするならエクスプローラーでそのファイルを選び、右クリックで表示されるメニューからコピーを選べば、そのファイルをコピーできます。
このような機能をプログラミング言語で実現する方法は難しくありません。多くのプログラミング言語にはファイルを操作する機能が用意されているので、それを活用してください。次からプログラムの中でファイルをコピーする方法について紹介します。
cpコマンドを使う
Linuxのターミナルを操作してファイルをコピーする場合、OSに付属しているcpコマンドを使います。そしてプログラムからcpコマンドを実行できればファイルのコピーが可能です。なおcpコマンドは次のように使います。
cpコマンドの使い方
cp [オプション]コピー元 コピー先
cpコマンドの使用例
$ ls dir1 file1 $ cp file1 file2 $ cp -r dir1 dir2 $ ls dir1 dir2 file1 file2
この例ではfile1をfile2にコピーし、続いてディレクトリのdir1をdir2にコピーしています。なおディレクトリとはWindowsのフォルダのことで、ディレクトリをコピーするためには「-r」オプションが必要です。
Rubyなどのプログラミング言語には外部コマンドを実行する機能があるので、cpコマンドを利用する文字列を作成し、それを実行することでファイルをコピーすることが可能です。
ライブラリを活用する
Rubyを含むプログラミング言語にはファイルを操作するための機能が組み込まれており、それを組み合わせることでファイルのコピーが可能です。なお、スキルさえあればOSを直接操作する機能を使ってゼロから作ることが可能ですが、ファイルを操作する便利なライブラリが用意されているならそれを使いましょう。
Rubyではファイルを操作するためのライブラリとしてFileUtilsモジュールが使えます。そしてこのモジュールはRubyをインストールすると同時に使える標準ライブラリの1つです。もし簡単なファイルのコピーをRubyのプログラムに組み込みたいなら、FileUtilsモジュールを活用してください。
FileUtilsのコピーを使う
先ほど紹介したようにRubyのプログラムでファイルをコピーするなら、FileUtilsモジュールの利用をおすすめします。なおFileUtilsモジュールにはコピー以外にもファイルを操作する便利な機能が幾つも用意されているので、ぜひ、利用してください。
次からFileUtilsでファイルのコピーに使われるcopyメソッドについて紹介します。
FileUtilsモジュールを使うには
先ほど紹介したようにFileUtilsモジュールはRubyの標準ライブラリの1つです。そのためRubyをインストールすると同時に利用できます。ただし、標準では読み込まれていないので、requireでモジュールを読み込みしなければなりません。FileUtilsモジュールを使うには、次の行を利用してください。
require 'fileutils'
FileUtilsのcopyメソッド
FileUtilsモジュールでファイルのコピーに使うのがcopyメソッドです。そしてFileUtilsのcopyメソッドは、2つの引数とオプションを使い、1つ目の引数のファイルを、2つ目の引数のファイルにコピーします。
なお、オプションは省略可能です。また、2つ目の引数にディレクトリを指定でき、その場合は指定したディレクトリの下にコピーします。
copyメソッドの文法
copy( コピー元のファイル名、コピー先のファイル名、[オプション] )
copyメソッドの例
require 'fileutils' FileUtils.copy('tmp.txt', 'val1.txt')
別名のcpを使う
Rubyの標準で使える多くのメソッドに別名が設定されており、そのどちらでも同じ機能を利用できます。そして今回紹介するFileUtilsのcopyメソッドの別名がcpメソッドです。
なおLinuxのターミナルなどで使えるファイルをコピーするコマンドがcpです。一方WindowsのDOSプロンプトで使えるのはcopyコマンドです。そのため使い慣れたコマンドと同じメソッドを選べます。
cpメソッドの文法
cp( コピー元のファイル名、コピー先のファイル名、[オプション] )
cpメソッドの例
require 'fileutils' FileUtils.cp('tmp.txt', 'val1.txt')
例外処理に組み込む
ファイルのコピーはサーバーの状況により失敗することがあります。そしてそのような場合、Rubyのプログラムがエラーで止まってしまうので、エラーで止めないためにbegin~rescue構文による例外処理が必要です。
例外処理にcopyメソッドを組み込む例
equire 'fileutils' begin FileUtils.copy('tmp.txt', 'val1.txt') rescue puts "ファイルコピーに失敗しました" end
外部コマンドによるファイルコピー
Rubyのプログラムからファイル単位でコピーするなら先ほど紹介したFileUtilsのcopyメソッドを利用します。しかしバックアップのように複数のファイルをまとめてコピーする場合は外部コマンドの方が便利です。
次から外部コマンドを利用したファイルのコピー方法について紹介します。
Rubyで外部コマンドを使うには
Rubyで外部コマンドを利用する方法は幾つかありますが、結果を取得できなかったり、標準エラーを取得できないなどの制限があるため、どれでも良い訳ではありません。ファイルをコピーする場合、その実行結果を取得し、もしエラーだった場合は例外処理が可能な方法を利用します。
そのため、標準出力、標準エラー出力、終了ステータスを取得できる標準のOpen3モジュールにあるcapture3メソッドを利用してください。なおOpen3モジュールを利用するにはrequireでモジュールの利用を指定しなければなりません。
capture3メソッドの使い方
標準出力, 標準エラー, プロセスの終了ステータス = Open3.capture3( コマンド )
capture3メソッドの例
require "open3" result, err, status = Open3.capture3("cp tmp1.txt vol1.txt")
rsyncコマンドを使う
バックアップのような複数のファイルをまとめてコピーする際によく使われるLinuxのコマンドがrsyncです。CentOSやUbuntuのようなLinuxのディストリビューションでは標準でインストールされており、macOSでも利用できます。
なおrsyncコマンドは、リモート環境(r)のファイルやディレクトリを同期(sync)するためのコマンドですが、サーバー内のファイルやディレクトリのコピーにも使えます。また、rysncには多くオプションがあり、コピー方法やメッセージなどを制御できます。
そして先ほど紹介いたcapture3メソッドに指定することで、Rubyのプログラムの中からも利用できます。
Rubyからrysncコマンドを実行する例
次にcapture3メソッドから外部コマンドとしてrysncを実行し、まとめてファイルをコピーする例を紹介します。
require 'fileutils' require 'open3' cmd = "rsync -ahv /var/www/html/rails /export/backup/" o, e, s = Open3.capture3(cmd)
この例は、rycnsコマンドを文字列としてcmdに格納し、Open3.capture3メソッドで実行する例です。そしてこのコマンドの実行結果が、o, e, sの3つのオブジェクトでチェックできます。
まとめ
今回、Rubyのプログラムの中でファイルをコピーする処理の作り方として、FileUtilsモジュールを利用する方法と外部コマンドを使う方法を紹介しました。単純なファイルのコピーにはFileUtilsモジュールは便利ですが、バックアップ用途のコピーにはrsyncコマンドが適しています。用途に応じて使い易い方法を採用しましょう。
なお、プログラムで自動的にファイルをコピーする処理は、常に正常に終了するとは限りません。そのためエラーが発生した場合の例外処理をセットで検討してください。
rysncコマンドの詳しい使い方は、こちらのサイトを参照してください。
【 rsync 】コマンド(その1)――ファイルやディレクトリを同期する:Linux基本コマンドTips(82) – @IT