Pathname#realpath over each entry in a directory

tldr: Having trouble getting the target of symlinks within a specified
directory.

My apologies for a very newbish question here.
Background: As a learning exercise I want to write a program that will
sync folders between my desktop and my Android phone using adb push.
I know there are already apps that do this, but it seems a nice starter
project to learn something from.

I have a script that will create a hidden desktop directory for each
type of file to be synced (music, pictures, movies, etc). I have a
script that will provide an entry on right click menus for “sync to
android” with sub-entries for each category. This creates a symlink to
the selected file or directory in the “sync” directory.

Problem: adb push does not work with symlinks. I need my “sync” script
to read over the symlinks in the sync directories and return the target
paths to adb push. I have tried any number of ways to make this
happen and come up short. Any assistance is needed. Examples of things
that do not work below:

Pathname("/#{Dir.home}/.ANDROIDMUSIC").each_entry.realpath => ‘foreach’:
no block given (LocalJumpError)

Dir.foreach("/#{Dir.home}/.ANDROIDMUSIC") { |entry|
Pathname(entry).realpath } => in ‘realpath’: No such file or directory -
/current/directory/with_file_from_specified_directory_appended.mp3

At the first example you should pass a block to the iterator

Pathname(Dir.home).each_entry {|entry| p entry.realpath }

The second, it’s probably what it’s telling you. The (actual) file

doesn’t exist.
Only the symlink.

I did

ln -s non-existing-dir/ my-symlink

And now I have a symlink called “my-symlink” pointing to a

“non-existing-dir”.

Now if I try:

Dir.foreach("/#{Dir.home}/") { |entry| p Pathname(entry).realpath }

It gives me

Errno::ENOENT: No such file or directory -
/Users/abinoam/non-existing-dir
from (irb):35:in realpath' from (irb):35:inrealpath’
from (irb):35:in block in irb_binding' from (irb):35:inforeach’
from (irb):35
from /Users/abinoam/.rvm/rubies/ruby-1.9.3-p429/bin/irb:16:in `’

If I just create the non-existing-dir

mkdir non-existing-dir

It just pass ok.

You’re going well!

Keep going,
Abinoam Jr.

Thank you so much for your assistance. The target of the symlink
definitely exists. In fact:

Pathname.new("/path/to/symlink/file.mp3").realpath =>
/path/to/target/of/symlink.mp3

With either:
Pathname("/#{Dir.home}/.ANDROIDMUSIC").each_entry {|entry| p
entry.realdirpath }

or

Dir.foreach("#{Dir.home}/.ANDROIDMUSIC/") { |entry| puts
Pathname(entry).realdirpath }

No error is returned but the output is unexpected. What is returned is
a path that does not exist. In essence it gives the path of the
directory from which I am running the script in the terminal, that path
with each filename appended, and the path of the parent directory. The
middle entry does not really exist. So you’re correct that the path
does not exist, but the script is somehow making it up, while the
symlink actually points to a real path. Thanks again for your help.

Almost there. It seems that using File.realdirpath almost works.

Dir.foreach("#{Dir.home}/.ANDROIDMUSIC/") { |entry| puts
File.realdirpath(entry, “#{music_source}”) }

returns the correct path for each target of a symlink in the specified
directory, but it also returns the path of that directory and the path
of the directory from which the script is executed. Anyone have
suggestions on how I can exclude those two entries? I certainly don’t
want to end up copying my entire home directory onto my phone by
accident.

The following seems to do what I want except for including the directory
from which the script is run (in this case my home directory).

def link_targets
music_destination = “/sdcard/Music/”
music_source = “#{Dir.home}/.ANDROIDMUSIC”
def push(source, destination)
adb push #{source} #{destination}
end
Dir.foreach("#{music_source}") { |entry| push
“#{File.realdirpath(entry, “#{music_source}”).to_s }”,
“#{music_destination}”}
end

link_targets

If anyone can suggest a way to modify the File.realdirpath command so
that it does not in fact return the home directory I would appreciate
it. I cannot, in fact, understand why it is doing this to begin with.

Also, if the symlink is to a directory instead of a file, will
File.realdirpath still work? Thanks in advance.

I’ve managed to get it working based on file extension, but that seems
inelegant. I don’t want to have to specify every possible audio format
out there just for the purpose of excluding these two directories. If
someone can let me know just why those two directories are included in
the output, I’d appreciate it. Finally, this does not work if an entire
directory is linked. That is, the directory is treated as “not a music
file” and the files within that directory are ignored rather than being
pushed. Suggestions for how to dig not only the specified directory,
but any subdirectories encountered? Thanks again. (Last response to my
own
question of the night, promise.)

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs