루비와 함께 존재하지 않는 디렉토리 만들기


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

1
@TWiStErRob는 : 다시는 내 의견을 읽고, 나에 대해 아무것도 말했다 fileutils또는 mkdir_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보다는?
Florin Asăvoaie

4
이름이 같은 일반 파일이 있다고 가정합니다. 이 경우 디렉토리를 만들 수 없습니다.
Mikołaj Rozwadowski

3
또한 경쟁 조건을 만듭니다. 파일은 확인 후 생성되기 전에 생성 될 수 있습니다.
돈 레바

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수정 자 형태로 사용하지 마십시오 .
Sebastian Palma

1
왜 단 1 줄이 아닌 5 줄의 코드를 작성해야하는지 설명해야합니까? 나는 당신이 시도보고 싶습니다.
Vidar


1
나는 이미했다. 그리고 나는 완전히 동의하지 않는다. 나는 그것이 바보라고 생각한다. 그래서 당신은 나를 깨우칠 수 있을까?
Vidar

6
이것은 당신이하려는 일이 아닌 모든 예외를 잡을 있으며 실제 응용 프로그램에서는 유지 보수를 어렵게 만드는 문제를 숨길 수 있습니다. 또한 예외를 조건부로 사용하는 것은 좋은 생각이 아닙니다. 하드웨어 의미에서 훨씬 느리게 실행됩니다 (현대 언어에서는 실제로 문제는 아니지만 여전히 코더로 경험하지 못하도록 만듭니다).
Ed_
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.