2013-10-09 18 views
109

existiert Ich versuche, ein Verzeichnis mit dem folgenden Code zu erstellen:Verzeichnis erstellen, wenn es mit Rubin nicht

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

jedoch Ich erhalte diese Fehlermeldung:

No such file or directory - /Users/Luigi/Desktop/Survey_Final/Archived/Survey/test (Errno::ENOENT)

Warum ist Dieses Verzeichnis wird nicht von der Dir.mkdir Anweisung oben erstellt?

+4

'File.Exists()' arbeitet auf Dateien und Ordnern. Es kennt den Unterschied nicht. –

Antwort

182

Sie versuchen wahrscheinlich verschachtelte Verzeichnisse zu erstellen. foo Unter der Annahme, nicht vorhanden ist, erhalten Sie no such file or directory Fehler für:

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

Um auf einmal verschachtelte Verzeichnisse zu erstellen, wird FileUtils benötigt:

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

Edit2: Sie müssen nicht FileUtils verwenden müssen, können Sie tut Systemaufruf (Update von @mu ist zu kurz, Kommentar):

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

Aber das scheint (zumindest für mich) als schlechten Ansatz als Sie verwenden externe "Werkzeug", die auf einigen Systemen nicht verfügbar sein kann (obwohl ich System ohne mkdir schwer vorstellen kann, aber wer weiß).

+5

'System 'mkdir', '-p', 'foo/bar'' wäre eine bessere Version dieses' System'-Aufrufs. Es gibt keinen Bedarf für einen zusätzlichen Shell-Prozess oder den üblichen Quoting/Escaping/Injection-Nonsense, der mit der Single-Argument-Version von 'system' kommt. –

+0

Danke, wusste nicht, was meinst du mit extra Shell-Prozess? – zrl3dx

+6

'system' startet'/bin/sh' um die 'mkdir -p" foo/bar "' string zu parsen und dann wird die Shell '/ bin/mkdir' laufen lassen. Also machst du zusätzliche Arbeit (erstelle die Befehlszeichenfolge, starte '/ bin/sh', um sie wieder auseinander zu ziehen) und ein Teil dieser zusätzlichen Arbeit lässt dich für Shell-Injection-Attacken offen (verbringe etwas Zeit in den CERT-Advisories für Ruby und Sie werden sehen, wie häufig dieses Problem ist). –

54

einfache Art und Weise:

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

Man soll File.directory benutzen? anstatt File.exists? –

+4

Angenommen, es gibt eine normale Datei mit demselben Namen. In diesem Fall konnte kein Verzeichnis erstellt werden. –

+2

Es erstellt auch eine Race-Bedingung. Die Datei kann nach der Überprüfung, aber vor der Erstellung erstellt werden. –

0

Wie wäre es nur Dir.mkdir('dir') rescue nil?

+2

Vermeiden Sie die Verwendung von 'rescue' in seiner Modifikatorform. –

+1

Warum sollte ich 5 Codezeilen anstelle von 1 schreiben? Ich würde es gerne sehen, wenn du es versuchst. – Vidar

+1

https://github.com/bbatsov/ruby-style-guide#no-rescue-modifiers einen Blick, bitte –

4

Eine weitere einfache Möglichkeit:

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

Verwandte Themen