So überprüfen Sie, ob mit einem Befehl in Ruby ein Verzeichnis / eine Datei / ein Symlink vorhanden ist

82

Gibt es eine einzige Möglichkeit, um festzustellen, ob ein Verzeichnis / eine Datei / ein Symlink / etc. Entität (allgemeiner) existiert?

Ich benötige eine einzelne Funktion, da ich ein Array von Pfaden überprüfen muss, bei denen es sich um Verzeichnisse, Dateien oder Symlinks handeln kann. Ich weiß, File.exists?"file_path"funktioniert für Verzeichnisse und Dateien, aber nicht für Symlinks (was ist File.symlink?"symlink_path").

claudiut
quelle
1
Welche Version von Ruby verwenden Sie? Datei existiert? arbeitet für Symlinks für mich in Ruby 1.9.2 in OS X 10.6.6
1
Zur Verdeutlichung: Bei Symlinks fragen Sie nach etwas, das zurückgegeben wird, truewenn der Symlink vorhanden ist, unabhängig davon, ob er letztendlich in einen Nicht-Symlink aufgelöst werden kann. Dh es sollte auch truefür defekte Links zurückkehren. File.exists?wird nur truefür einen Symlink zurückgegeben, der nicht defekt ist.
Kelvin

Antworten:

147

Das Standard-Dateimodul verfügt über die üblichen verfügbaren Dateitests :

RUBY_VERSION # => "1.9.2"
bashrc = ENV['HOME'] + '/.bashrc'
File.exist?(bashrc) # => true
File.file?(bashrc)  # => true
File.directory?(bashrc) # => false

Sie sollten dort finden können, was Sie wollen.


OP: "Danke, aber ich brauche alle drei wahr oder falsch"

Offensichtlich nicht. Ok, versuchen Sie etwas wie:

def file_dir_or_symlink_exists?(path_to_file)
  File.exist?(path_to_file) || File.symlink?(path_to_file)
end

file_dir_or_symlink_exists?(bashrc)                            # => true
file_dir_or_symlink_exists?('/Users')                          # => true
file_dir_or_symlink_exists?('/usr/bin/ruby')                   # => true
file_dir_or_symlink_exists?('some/bogus/path/to/a/black/hole') # => false
der Blechmann
quelle
1
Ich würde davon abraten, eine rohe String-Verkettung ( ENV['HOME'] + '/.bashrc') durchzuführen, die möglicherweise nicht plattformübergreifend funktioniert. Sie sollten Ruby File Joins verwenden und auch, Rails.rootwenn Sie Rails verwenden. File.exists?(Rails.root.join('db', 'my_seeds.csv')
Cyril Duchon-Doris
2
Es funktioniert garantiert nicht plattformübergreifend, da Windows nichts über Bash und damit über .bashrc weiß. Aber es würde auf einer * nix-basierten Plattform funktionieren. Die Verwendung von /ist jedoch nicht das Problem, da Rubys E / A unter Windows automatisch von Schrägstrichen in Schrägstriche umgewandelt wird .
der Blechmann
Vielleicht stimmte das im Dezember 2016, aber Windows weiß heutzutage definitiv etwas über Bash. :-) Ich kann bashin das Startmenü tippen und im resultierenden Konsolenfenster cat ~/.bashrceine Ausgabe erzeugen. ¯ \ _ (ツ) _ / ¯
Jonathan Gilbert
Die Antwort von Cyril ist leider nicht ganz richtig - String-Verkettung funktioniert unter Windows für "File.exist?" prüft, wie der Blechmann bereits betonte. Ich habe diesen Kommentar hier nur hinzugefügt, um ihn zu bestätigen.
Shevy
14

Warum definieren Sie nicht Ihre eigene Funktion File.exists?(path) or File.symlink?(path)und nutzen diese?

Gintautas Miliauskas
quelle
2
@Clawsy Ich denke, Sie vermissen Gintautas 'Punkt: Sie sind ein Programmierer - wenn die Funktion, die Sie benötigen, nicht vorhanden ist, können Sie sie erstellen.
Telemachos
4
Warum das Rad neu erfinden, wenn es bereits Teil der Sprache ist?
der Blechmann
11
Ich finde es sehr nützlich, bei der Programmierung nicht zu sehr auf Details zu achten. Wenn Sie einen einfachen Weg kennen, um ein Problem zu lösen, tun Sie es einfach. Wenn Sie einige Zeit später einen besseren Weg finden, können Sie jederzeit zurückgehen und das Problem beheben. Das Definieren einer neuen Funktion ist in dieser Situation ein Kinderspiel.
Gintautas Miliauskas
5
Die Funktionalität ist jedoch bereits in die Sprache integriert und einfach zu bedienen. Anschließend wird gelesen, was verfügbar ist, und der Anruf wird hinzugefügt. Das Schreiben von Code zur Implementierung bereits vorhandener Funktionen, nur weil Sie sich nicht die Zeit genommen haben, ein RDoc zu lesen, das mit der Sprache geliefert wird, passt einfach nicht zu mir. Durch diese Logik könnten Sie am Ende die Standardbibliothek neu schreiben.
der Blechmann
2
File.exist verwenden? anstelle von File.exists? wie dies in Ruby veraltet 2.2.0: ruby-doc.org/core-2.2.0/File.html#method-c-exists-3F
atw