Forum: Ruby Shell scripting & Windows/Linux Paths

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
01cd7a5d8751789819701518f3fe6ffa?d=identicon&s=25 Juan Zanos (Guest)
on 2009-03-10 17:21
(Received via mailing list)
What's the best way to launch executables with Ruby in a way that
paths and other command line parameters work on both Windows and Linux?

Juan
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-03-10 17:30
(Received via mailing list)
2009/3/10 Juan Zanos <juan_zanos@talkhouse.com>:
> What's the best way to launch executables with Ruby in a way that paths and
> other command line parameters work on both Windows and Linux?

I'm not sure why you are asking for "other command line parameters"
but for paths forward slashes as separators are OK on both platforms.

Kind regards

robert
149379873fe2cb70e550c6bff8fedd0c?d=identicon&s=25 Jeff Schwab (Guest)
on 2009-03-10 17:35
(Received via mailing list)
Robert Klemme wrote:
> 2009/3/10 Juan Zanos <juan_zanos@talkhouse.com>:
>> What's the best way to launch executables with Ruby in a way that paths and
>> other command line parameters work on both Windows and Linux?
>
> I'm not sure why you are asking for "other command line parameters"
> but for paths forward slashes as separators are OK on both platforms.

For relative paths only.  A path beginning with / will be misinterpreted
as a command-line switch by most Windows commands.
01cd7a5d8751789819701518f3fe6ffa?d=identicon&s=25 Juan Zanos (Guest)
on 2009-03-10 17:36
(Received via mailing list)
Yes, I'm mostly concerned with paths.   I'd like to write everything
in Unix style and just have it  automatically converted somehow so
everything stays relatively legible.
9e2504e0b74e5384af09ce8a660afac4?d=identicon&s=25 Pascal J. Bourguignon (Guest)
on 2009-03-10 17:55
(Received via mailing list)
Juan Zanos <juan_zanos@talkhouse.com> writes:
>> 2009/3/10 Juan Zanos <juan_zanos@talkhouse.com>:
>>> What's the best way to launch executables with Ruby in a way that
>>> paths and
>>> other command line parameters work on both Windows and Linux?
> Yes, I'm mostly concerned with paths.   I'd like to write everything
> in Unix style and just have it  automatically converted somehow so
> everything stays relatively legible.

IMO, the best way is not to use any literal path.

Keep a map of executable => path that you load at startup from a
different configuration file (or source) depending on whether you run
on Microsoft Windows or on Unix.  Actually this would even allow you
to adapt your program to different Unix systems, with different
"standard" places for the various executables.

If you try that, you will see that it gives you some level of
abstraction in the management of pathnames so  your program becomes
even clearer.
770048af205ed307b8cf35ae2282ee2f?d=identicon&s=25 Michael Malone (Guest)
on 2009-03-10 21:08
(Received via mailing list)
Juan Zanos wrote:
> Yes, I'm mostly concerned with paths.   I'd like to write everything
> in Unix style and just have it  automatically converted somehow so
> everything stays relatively legible.
>
>
One good pattern for dealing with this I have seen is simply to have a
shell_command method somewhere, so you can do different things if you're
on different OSs.  And to figure out dynamically which OS you're working
with,  use this:

require 'rbconfig'
if Config::CONFIG["target_os"] == 'linux'
    OS = 'linux'
else
    OS = 'windows' #presumably
end

Yes, I am aware that that code is specific to linux/windows but it was
enough for me.  You're a puts call away from getting the required
options.  That sort of thing can make life easier if you want to
redirect to /dev/null or NUL and only want to change your command in one
place.

Michael

=======================================================================
This email, including any attachments, is only for the intended
addressee.  It is subject to copyright, is confidential and may be
the subject of legal or other privilege, none of which is waived or
lost by reason of this transmission.
If the receiver is not the intended addressee, please accept our
apologies, notify us by return, delete all copies and perform no
other act on the email.
Unfortunately, we cannot warrant that the email has not been
 altered or corrupted during transmission.
=======================================================================
87ef5d1e14b148eb596433bc17ffe690?d=identicon&s=25 Leo (Guest)
on 2009-03-10 22:32
(Received via mailing list)
> Yes, I'm mostly concerned with paths.   I'd like to write everything  
> in Unix style and just have it  automatically converted somehow so  
> everything stays relatively legible.

You shouldn't write a filename or whatever in unix style. Ruby has
excellent libraries for dealing with pathnames. Take a look at the
File and the Pathname classes, which provide everything you need for
writing cross-plattform apps, and use the methods they provide.
9e2504e0b74e5384af09ce8a660afac4?d=identicon&s=25 Pascal J. Bourguignon (Guest)
on 2009-03-11 11:10
(Received via mailing list)
Michael Malone <michael.malone@tait.co.nz> writes:

>
> redirect to /dev/null or NUL and only want to change your command in one
> place.

It would be much better to have subclasses for each OS.  This way, you
could generate commands for one OS, from another OS, and send it
remotely thru ssh or some other way.

(class OS
  (def genGetRootDirectory
    (subclassResponsibility)
   end)
  (def genGetListOfDirectoriesInDirectory(directory)
    (subclassResponsibility)
  end)
  (def genGetListOfFilesInDirectory(directory)
    (subclassResponsibility)
  end)
  (def genRemoteExecute(command)
    (subclassResponsibility)
   end)
  (def execute(command)
    (subclassResponsibility)
   end)
end)


(class Linux < OS
  (def genGetRootDirectory
    (Directory . new "/")
   end)
  (def genGetListOfDirectoriesInDirectory(directory)
    (Command . new "find #{(quoteShellArgument (directory . path))}/*
-prune -type d -print")
  end)
  (def genGetListOfFilesInDirectory(directory)
    (Command . new "find #{(quoteShellArgument (directory . path))}/*
-prune \\( \\! -type d \\) -print")
  end)
  (def genRemoteExecute(command,host,user=nil)
    (Command . new "ssh #{(user ? user+"@" : "")}#{host} #{(command .
text)}")
   end)
  (def execute(command)
    (system (command . text))
   end)
end)

and similarly for MSWindows.

So you can write:

(localHost = ((Config::CONFIG["target_os"] == 'linux') ? (Linux . new) :
(MSWindows . new)))
(remoteDoze  = (MSWindows . new))
(remoteLinux = (Linux . new))

(localHost . execute (localHost . genRemoteExecute (remoteDoze .
genGetListOfFiles (remoteDoze . genGetRootDirectory))))
(localHost . execute (localHost . genRemoteExecute (remoteLinux .
genGetListOfFiles (remoteLinux . genGetRootDirectory))))
(localHost . execute (localHost . genGetListOfFiles (localHost .
genGetRootDirectory)))
This topic is locked and can not be replied to.