ディレクトリ操作するクラス。
成果物
情報源
Dir
ディレクトリ操作するクラス。Enumratableを継承している。
特異メソッド
[] chdir children chroot delete each_child empty? entries exist? exists? foreach getwd glob home mkdir new open pwd rmdir unlink
インスタンスメソッド
children close each each_child fileno inspect path pos pos= read rewind seek tell to_path
[]
, glob
ワイルドカード展開する。パターンにマッチしたファイル名を配列で返す。ディレクトリ、ファイル、リンク等にヒットする。
Dir.glob("*") #=> ["bar", "foo"] Dir.glob("*", File::FNM_DOTMATCH) #=> [".", "..", "bar", "foo"] Dir.glob('*') {|f| p f}
APIは以下。
self[*pattern, base: nil, sort: true] -> [String][permalink][rdoc][edit] glob(pattern, flags = 0, base: nil, sort: true) -> [String] glob(pattern, flags = 0, base: nil, sort: true) {|file| ...} -> nil
pattern
には以下のメタ文字が使える。
メタ文字 | 概要 |
---|---|
* |
空文字列を含む任意の文字列。 |
? |
任意の一文字 |
[] |
鈎括弧内のいずれかの文字。- で範囲[a-z] 。^ か! で否定[^abc] 。 |
{} |
組合せ展開。a{1,2,3} =a1 ,a2 ,a3 。{} はネストできる。 |
**/ |
ディレクトリの再帰的マッチ。 |
flags
にはFile::Constantsを指定する。
File::Constants | 概要 |
---|---|
FNM_CASEFOLD |
アルファベットの大小文字を区別しない |
FNM_DOTMATCH |
ワイルドカード * , ? , [] が先頭の . にマッチするようになる |
FNM_NOESCAPE |
エスケープ文字 `\' を普通の文字とみなす |
FNM_PATHNAME |
ワイルドカード * , ? , [] が / にマッチしなくなる。シェルと同等 |
FNM_SYSCASE |
case hold なファイルシステムの場合、FNM_CASEFOLD の値になり、そうでなければゼロ。 |
chdir
カレントディレクトリを変更する。成功すると0
を返す。
Dir.chdir('/tmp') p Dir.pwd #=> /tmp
ブロックがあるとカレントディレクトリの変更はブロック内のみとなる。
Dir.chdir('/tmp') Dir.chdir('/tmp/work') {|path| p path #=> /tmp/work p Dir.pwd #=> /tmp/work } p Dir.pwd #=> /tmp
children
, each_child
, entries
, foreach
指定したパスがもつ子の名前一覧を配列で返す。.
,..
を除く。Encodingを指定しなければファイルシステムのそれになる。
Dir.children('/tmp/work') Dir.children('/tmp/work', encoding:Encoding::UTF_8)
インスタンスメソッド版もある。引数なし。
Dir.open('.'){|d| p d.children # => ["bar", "foo"] }
ループ版もある。同様にEncodingを指定できる。
Dir.each_child('.'){|f| p f } #=> "bar" # "foo"
.
と..
を含む版。同様にEncodingを指定できる。
Dir.entries('.') #=> [".", "..", "bar", "foo"]
同上の別名版。配列でなくEnumratorを返す。
Dir.foreach('.').to_a Dir.foreach('.') {|f| p f}
chroot
ルートディレクトリを変更する。スーパーユーザだけが変更できる。
Dir.chroot("./")
権限がないと以下のように怒られる。
Operation not permitted @ dir_s_chroot - ./ (Errno::EPERM)
delete
, rmdir
, unlink
ディレクトリを削除する。ディレクトリは空でなければならない。成功すると0
を返す。
Dir.mkdir '/tmp/work/test' Dir.delete '/tmp/work/test' Dir.mkdir '/tmp/work/test' Dir.rmdir '/tmp/work/test' Dir.mkdir '/tmp/work/test' Dir.unlink '/tmp/work/test'
empty?
ディレクトリが空のとき真を返す。
Dir.mkdir '/tmp/work/test' Dir.rmdir if Dir.empty? '/tmp/work/test'
exist?
ディレクトリが存在するなら真を返す。
d = '/tmp/work/test' Dir.mkdir d unless Dir.exist? d
なお、File.directory?
も同様。
d = '/tmp/work/test' Dir.mkdir d unless File.directory? d
getwd
, pwd
カレントディレクトリのフルパスを返す。
Dir.chdir("/tmp") #=> 0 Dir.getwd #=> "/tmp" Dir.pwd #=> "/tmp"
home
現在のユーザまたは指定されたユーザのホームディレクトリを返す。
Dir.home Dir.home('username')
Dir.home や Dir.home("root") は File.expand_path("~") や File.expand_path("~root") とほぼ同じです。
File.expand_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"
mkdir
ディレクトリを作成する。
mkdir(path, mode = 0777) -> 0
p File.umask #=> 2 Dir.mkdir('t', 0666) p "%#o" % (07777 & File.stat('t').mode) #=> "0664" p File.umask #=> 2 Dir.mkdir('t', 0666) p "%#o" % (07777 & File.stat('t').mode) #=> "0664"
new
, open
ディレクトリのストリームを開いて返す。
new(path) -> Dir new(path, encoding: Encoding.find("filesystem")) -> Dir open(path) -> Dir open(path, encoding: Encoding.find("filesystem")) -> Dir open(path) {|dir| ...} -> object open(path, encoding: Encoding.find("filesystem")) {|dir| ...} -> object
ブロックを指定して呼び出した場合は、ディレクトリストリームを引数としてブロックを実行します。ブロックの実行が終了すると、ディレクトリは自動的にクローズされます。ブロックの実行結果を返します。
Dir.new('/tmp') {|dir| p dir} Dir.open('/tmp') {|dir| p dir}
ブロックがあれば自動的にclose
されるのが嬉しい。C#でいうusing(){}
でありPythonでいうwith open() as f:
。
疑問
所感
実際にコードを書くとなると色々疑問が出てきそう。そのときに都度調べよう。今はAPIをさらっと把握するだけに留める。
対象環境
- Raspbierry pi 4 Model B
- Raspberry Pi OS buster 10.0 2020-08-20 ※
- bash 5.0.3(1)-release
- Ruby 3.0.2
$ uname -a Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux