smmr14
smmr14

Reputation: 161

How to create nested directories using Net::SFTP (Ruby)

I am trying to create multiple directories at once. Currently, the sftp.mkdir! path only creates one directory level at a time. For example, I can create /test, and then have to make another directory /test/secure_token and so on so forth. Is there a way I can create /test/secure_token in one call rather than two?

Upvotes: 2

Views: 916

Answers (2)

Vajk Hermecz
Vajk Hermecz

Reputation: 5702

I did not manage to find a solution for this, so created the following method:

def sftp_makedirs(sftp, remotedir)
  return if remotedir == "."
  return if sftp.file.directory?(remotedir)
  raise StandardError, "path '#{remotedir}' already exists, but not a dir"
rescue Net::SFTP::StatusException  #(2, "no such file")
  sftp_makedirs(sftp, File.dirname(remotedir))
  sftp.mkdir!(remotedir)
end

How it works:

  • It terminates the recursion when reaching the empty-path (current-dir aka .)
  • It terminates if the directory exists
  • It raises an exception if the path exists but is not a directory
  • If the path does not exist, it makes sure its base exists, and creates the last level of the path

Upvotes: 1

Joshua Pereira
Joshua Pereira

Reputation: 321

I ran the following ruby script with host, username, and password passed as command line arguments:

require 'net/sftp'

Net::SFTP.start(host, username, password: password) do |sftp|
  sftp.mkdir!("/home/#{username}/test/test2")
end

And was able to successfully create a multi-level directory on the remote host.

The rubydoc doesn't mention that #mkdir! cannot create multi-level directories, and it even gives an example argument as "/path/to/directory"

https://www.rubydoc.info/github/net-ssh/net-sftp/Net%2FSFTP%2FSession:mkdir!

You shouldn't have trouble if you just pass the entire path of the directory you're trying to create, so perhaps it's a weird quirk of your remote host? Hard to say without additional information.

Upvotes: -1

Related Questions