Rubyで存在しない場合はディレクトリを作成する


156

次のコードでディレクトリを作成しようとしています:

Dir.mkdir("/Users/Luigi/Desktop/Survey_Final/Archived/Survey/test")
    unless File.exists?("/Users/Luigi/Desktop/Survey_Final/Archived/Survey/test")  

ただし、次のエラーが表示されます。

そのようなファイルまたはディレクトリはありません-/ Users / Luigi / Desktop / Survey_Final / Archived / Survey / test(Errno :: ENOENT)

このディレクトリがDir.mkdir上記のステートメントで作成されないのはなぜですか?


4
File.exists?()ファイルとフォルダで機能します。それは違いを知りません。
Tin Man

回答:


263

おそらくネストされたディレクトリを作成しようとしています。foo存在しないと仮定すると、次のno such file or directoryエラーが表示されます。

Dir.mkdir 'foo/bar'
# => Errno::ENOENT: No such file or directory - 'foo/bar'

ネストされたディレクトリを一度に作成するにFileUtilsは、以下が必要です。

require 'fileutils'
FileUtils.mkdir_p 'foo/bar'
# => ["foo/bar"]

Edit2:を使用するFileUtils必要はありません。システムコールを実行できます(@muからの更新はコメントが短すぎます):

> system 'mkdir', '-p', 'foo/bar' # worse version: system 'mkdir -p "foo/bar"'
=> true

しかし、それは(少なくとも私には)一部のシステムでは利用できない可能性のある外部「ツール」を使用している場合よりも悪いアプローチのようです(ただし、がないシステムはほとんど想像できませんmkdirが、誰が知っていますか)。


5
system 'mkdir', '-p', 'foo/bar'そのsystem呼び出しのより良いバージョンになるでしょう。の単一引数バージョンに付属している追加のシェルプロセスや通常の引用/エスケープ/注入のナンセンスは必要ありませんsystem
muが短すぎる

6
system文字列/bin/shを解析するために起動しmkdir -p "foo/bar"、シェルが実行されます/bin/mkdir。つまり、追加の作業(コマンド文字列を作成し、起動/bin/shして再度引き離す)を行っており、その追加の作業の一部は、シェルインジェクション攻撃の余地を残しています(RubyのCERTアドバイザリでしばらく時間を過ごすと、一般的な方法がわかります)この問題です)。
muが短すぎる

1
@muistooshort @ zrl3dx system呼び出しはfileutils再びよりも優れていますか?私はWindowsを使用しておりmkdir_p、解析するためにサブシェルを生成することなく問題なくmkdir -p機能します。そのグラッドfileutils答えの最初の選択肢です。
TWiStErRob 2015

1
@TWiStErRob:もう一度私のコメントを読んで、私は約何も言わなかったfileutilsmkdir_p、私が言っているすべてはそれがあるsystem command, arg1, arg2, ...よりも良好ですsystem command_with_arguments
muが短すぎる

3
@muistooshortああ、申し訳ありませんが、悪いオプションを実行するより良い方法があると言っているだけです:)
TWiStErRob

71

簡単な方法:

directory_name = "name"
Dir.mkdir(directory_name) unless File.exists?(directory_name)

8
File.directoryを使用する必要がありますか?File.existsではなく?
FlorinAsăvoaie

4
同じ名前の通常のファイルがあるとします。このような場合、ディレクトリを作成できませんでした。
MikołajRozwadowski

3
また、競合状態が発生します。チェック後、作成前にファイルが作成される場合があります。
Don Reba

25

別の簡単な方法:

Dir.mkdir('tmp/excel') unless Dir.exist?('tmp/excel')


ネストされたディレクトリを作成する場合、これは機能しません。たとえば、私は次のディレクトリを作成したかった/home/jignesh/reports/testが、このソリューションを使用して発生しましたRUBY (Errno::ENOENT), no such file or directory @ dir_s_mkdir。したがって、信頼できるソリューションが使用されていますFileUtils.mkdir_p
Jignesh Gohel

-5

どうDir.mkdir('dir') rescue nilですか?


3
rescue修飾子形式での使用は避けてください。
セバスチャンパルマ

1
なぜ1行ではなく5行のコードを記述する必要があるのか​​を説明してください。ぜひやってみてください。
Vidar


1
私はすでにそうしました、そして私は全く同意しません、それはばかげていると思うので、あなたは私を啓発することができますか?
Vidar

6
これは、キャッチう任意のあなたがしようとしているされていないものを、例外をし、現実世界のアプリで難しいメンテナンスを作る問題を隠してしまいます。また、例外を条件として使用するのは良い考えではありません。ハードウェアの意味で、例外の実行速度は非常に遅くなります(現代の言語では実際には問題ではないかもしれませんが、コーダーとしての経験がないように見えます)。
Ed_ 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.