Jak sprawdzić, czy katalog / plik / dowiązanie symboliczne istnieje z jednym poleceniem w Rubim


83

Czy istnieje jeden sposób na wykrycie, czy katalog / plik / dowiązanie symboliczne / etc? istota (bardziej uogólniona) istnieje?

Potrzebuję jednej funkcji, ponieważ muszę sprawdzić tablicę ścieżek, które mogą być katalogami, plikami lub dowiązaniami symbolicznymi. Wiem, że File.exists?"file_path"działa dla katalogów i plików, ale nie dla linków symbolicznych (co jest File.symlink?"symlink_path").


1
Jakiej wersji Rubiego używasz? Plik istnieje? działa dla mnie dla linków symbolicznych w Ruby 1.9.2 w OS X 10.6.6

1
Dla wyjaśnienia: w przypadku dowiązań symbolicznych pytasz o coś, co zwraca, truejeśli dowiązanie symboliczne istnieje, niezależnie od tego, czy ostatecznie można je przekształcić w nie dowiązanie symboliczne. Oznacza to, że powinien powrócić również w trueprzypadku uszkodzonych linków. File.exists?zwróci tylko truedla łącza symbolicznego, które nie jest uszkodzone.
— Kelvin

Odpowiedzi:


147

Standardowy moduł plików ma dostępne zwykłe testy plików :

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

Powinieneś być w stanie znaleźć tam to, czego chcesz.


OP: „Dziękuję, ale potrzebuję wszystkich trzech prawdy lub fałszu”

Oczywiście, że nie. Ok, spróbuj czegoś takiego:

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

1
Odradzałbym konkatenację nieprzetworzonych ciągów znaków ( ENV['HOME'] + '/.bashrc'), co może nie działać na wielu platformach. Powinieneś użyć złączeń Ruby File i dlaczego nie zacząć od tego, Rails.rootjeśli używasz Railsów. File.exists?(Rails.root.join('db', 'my_seeds.csv')
— Cyril Duchon-Doris

2
Gwarantuje się, że nie będzie działać na wielu platformach, ponieważ system Windows nie wie o Bash, a zatem o .bashrc. Ale działałoby na platformie opartej na * nix. Użycie /nie jest jednak problemem, ponieważ IO Rubiego automatycznie konwertuje z ukośników w przód na ukośniki w systemie Windows .
— Tin Man

Może to prawda w grudniu 2016, ale Windows pewno nie wie o Bash te dni. :-) Mogę pisać bashw menu Start, aw wynikowym oknie konsoli cat ~/.bashrcgeneruje dane wyjściowe. ¯ \ _ (ツ) _ / ¯
— Jonathan Gilbert

Odpowiedź Cyrila nie jest niestety w pełni poprawna - konkatenacja ciągów CZY działa w systemie Windows dla "File.exist?" czeki, jak już wskazał Blaszany Człowiek. Dodałem ten komentarz tylko po to, aby to potwierdzić.
— shevy

14

Dlaczego nie zdefiniować własnej funkcji File.exists?(path) or File.symlink?(path)i jej nie wykorzystać?


2
@Clawsy Myślę, że brakuje ci punktu Gintautasa: jesteś programistą - jeśli funkcja, której potrzebujesz, nie istnieje, możesz ją stworzyć.
— Telemachus

4
Po co wymyślać koło na nowo, skoro jest już częścią języka?
— Tin Man

11
Uważam, że bardzo przydatne jest unikanie zbytniej obsesji na punkcie szczegółów w programowaniu. Jeśli znasz prosty i prosty sposób rozwiązania problemu, zrób to. Jeśli jakiś czas później znajdziesz lepszy sposób, zawsze możesz wrócić i naprawić. Zdefiniowanie nowej funkcji jest w tej sytuacji oczywiste.
— Gintautas Miliauskas

5
Ale ta funkcjonalność jest już wbudowana w język i jest prosta w użyciu. Następnie trzeba przeczytać, co jest dostępne, i dodać wezwanie. Pisanie kodu w celu zaimplementowania funkcjonalności, która już istnieje, tylko dlatego, że nie poświęciłeś czasu na przeczytanie RDoc, który jest dostarczany z językiem ... po prostu mi nie pasuje. Zgodnie z tą logiką możesz skończyć przepisując standardową bibliotekę.
— Tin Man,

2
Użyj File.exist? zamiast File.exists? ponieważ jest to przestarzałe w Ruby 2.2.0: ruby-doc.org/core-2.2.0/File.html#method-c-exists-3F
— atw
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.