创建目录(如果Ruby不存在)

Lui*_*igi 145 ruby

我正在尝试使用以下代码创建一个目录:

Dir.mkdir("/Users/Luigi/Desktop/Survey_Final/Archived/Survey/test")
    unless File.exists?("/Users/Luigi/Desktop/Survey_Final/Archived/Survey/test")  
Run Code Online (Sandbox Code Playgroud)

但是,我收到此错误:

没有这样的文件或目录 - /用户/路易吉/桌面/ Survey_Final /归档/调查/测试(错误:: ENOENT)

为什么Dir.mkdir上面的语句没有创建此目录?

zrl*_*3dx 241

您可能正在尝试创建嵌套目录.假设foo不存在,您将收到以下no such file or directory错误:

Dir.mkdir 'foo/bar'
# => Errno::ENOENT: No such file or directory - 'foo/bar'
Run Code Online (Sandbox Code Playgroud)

要一次创建嵌套目录,FileUtils需要:

require 'fileutils'
FileUtils.mkdir_p 'foo/bar'
# => ["foo/bar"]
Run Code Online (Sandbox Code Playgroud)

Edit2:你不必使用FileUtils,你可以做系统调用(从@mu更新是太短评论):

> system 'mkdir', '-p', 'foo/bar' # worse version: system 'mkdir -p "foo/bar"'
=> true
Run Code Online (Sandbox Code Playgroud)

但这似乎(至少在我看来)是一种更糟糕的方法,因为你使用的外部"工具"在某些系统上可能无法使用(虽然我很难想象系统没有mkdir,但谁知道).

  • `system`将启动`/ bin/sh`来解析`mkdir -p"foo/bar"`字符串,然后shell将运行`/ bin/mkdir`.所以你正在做额外的工作(创建命令字符串,启动`/ bin/sh`再将它拉开)并且一些额外的工作会让你对shell注入攻击开放(花一些时间在CERT顾问中为Ruby和你会看到这个问题有多常见). (6认同)
  • `system'mkdir',' - p','foo/bar'`将是`system`调用的更好版本.不需要额外的shell进程或者`system`的单个参数版本附带的通常的引用/转义/注入废话. (5认同)
  • @muistooshort啊,对不起,所以你只是说有一个更好的方法来做坏选项:) (3认同)
  • @muistooshort @zrl3dx `system` 调用又如何比 `fileutils` 更好?我在 Windows 上,并且 `mkdir_p` 工作得很好,而不会产生子shell 只是为了解析无论如何都会失败的 `mkdir -p`。很高兴 `fileutils` 是答案中的第一个选择。 (2认同)

小智 66

简单方法:

directory_name = "name"
Dir.mkdir(directory_name) unless File.exists?(directory_name)
Run Code Online (Sandbox Code Playgroud)

  • 一个人应该使用File.directory?而不是File.exists? (8认同)
  • 假设有一个具有相同名称的普通文件.在这种情况下,您无法创建目录. (4认同)
  • 它也会造成竞争条件.可以在检查之后但在创建之前创建该文件. (3认同)

小智 21

另一个简单方法:

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

  • 如果您想创建嵌套目录,那么这不起作用。例如,我想创建以下目录`/home/jignesh/reports/test`,但使用此解决方案引发了`RUBY (Errno::ENOENT),没有这样的文件或目录@ dir_s_mkdir`。所以可靠的解决方案是使用“FileUtils.mkdir_p” (3认同)