[windows 9*] how to get the output of commands which contain backslashes?

T

Tobias Reif

Hi

I have to deal with the annoying shell of Windows.
Some stuff works OK via

SHELL =
if CONFIG["arch"] =~ /win/
# more stuff based on www.ruby-talk.org/9739, thanks Phil :)

... but I can't get the output of commands which include backslashes.

Often they can be replaced with forward slashes, eg when a file path
is passed as arg to a program.
But if the strings which are passed directly to the shell contain
backslashes, eg when the program itself is called via a path, then
there is no output.

# those work: (don't contain backslashes)
puts `command.com /c ver`
# Windows Millennium [Version 4.90.3000]
puts `command.com /c ruby -v`
# ruby 1.6.5 (2001-09-19) [i386-cygwin]

# this works on the commandline:
# \for-programs\use\tidy\tidy.exe -v
# HTML Tidy for Windows released on 1st February 2003

# this doesn't work (as expected):
# /for-programs/use/tidy/tidy.exe -v
# Befehl oder Dateiname nicht gefunden.
# [command not found]

# these don't work (nothing printed)
# how to get this to work?
puts `command.com /c \for-programs\use\tidy\tidy.exe -v`
puts `command.com /c \\for-programs\\use\\tidy\\tidy.exe -v`

# also doesn't work (as expected):
puts `command.com /c /for-programs/use/tidy/tidy.exe -v`
# Befehl oder Dateiname nicht gefunden.
# [command not found]

I tried various stuff

def shell command
#full_command = SHELL+' '+command.gsub(/\\/,'\&\&')
# or
# full_command = SHELL+' '+command.dump
`#{full_command}`
end

... but nothing works so far. No error message, but also no output.

How to escape a backslash in order to pass a single backslash to the
shell?

I appreciate any solution, even dirty hacks and quirky workarounds :)

Tobi
 
U

U.Nakamura

Hello,

In message "[windows 9*] how to get the output of commands which contain backslashes?"
| How to escape a backslash in order to pass a single backslash to the
| shell?
|
| I appreciate any solution, even dirty hacks and quirky workarounds :)

Solution A:
cmd = '\for-programs\use\tidy\tidy.exe -v'
`command.com /c #{cmd}`

Solution B:
`command.com /c \for-programs\use\\tidy\\tidy.exe -v`


Regards,
 
U

U.Nakamura

Hello,

In message "Re: how to get the output of commands which contain backslashes?"
| Does your code work for you, on a Win9* (Windows ME) box?

Oh, sorry, I only tested on my WinXP box.
I have Win98SE test envrionment on my home, but now I'm on
office...


| > Solution B:
| > `command.com /c \for-programs\use\\tidy\\tidy.exe -v`
|
| I wrote:
| # these don't work (nothing printed)
| puts `command.com /c \for-programs\use\tidy\tidy.exe -v`
| puts `command.com /c \\for-programs\\use\\tidy\\tidy.exe -v`

Hmmm, so, can you try this?
`command.com /c \\for-programs\use\\tidy\\tidy.exe -v`



Regards,
 
T

Tobias Reif

Hi

U.Nakamura said:
| Does your code work for you, on a Win9* (Windows ME) box?

Oh, sorry, I only tested on my WinXP box.

Your code

`command.com /c \for-programs\use\\tidy\\tidy.exe -v`

works on XP?
I have Win98SE test envrionment on my home, but now I'm on
office...

It would be great if you could test it on Win9*.
| > `command.com /c \for-programs\use\\tidy\\tidy.exe -v`
|
| I wrote:
| # these don't work (nothing printed)
| puts `command.com /c \for-programs\use\tidy\tidy.exe -v`
| puts `command.com /c \\for-programs\\use\\tidy\\tidy.exe -v`

Hmmm, so, can you try this?
`command.com /c \\for-programs\use\\tidy\\tidy.exe -v`

What's the difference to the code above which I tested already and which
doesn't work?
Are you sure about the "\\" mixed with "\"?

Here is your code and a line with an added "\":

puts `command.com /c \\for-programs\use\\tidy\\tidy.exe -v`
puts `command.com /c \\for-programs\\use\\tidy\\tidy.exe -v`

Neither produces any output. That's the problem :(

Tobi
 
C

Chris Morris

I've got the following routines in a win.rb file that I always require
when I need to do shell stuffs, and I've yet to have any problems. The
excerpt is part of a collection of misc. stuffs you can get here:
http://www.clabs.org/dl/clutil/. Works with 1.6/1.8. (I thought I'd read
somewhere that these substitute routines wouldn't be needed anymore in
1.8, but a brief attempt without them failed, so I just stuck to it --
it's habitual now for me to install this on each box I've got Ruby on
and I always require it).

# MENON Jean-Francois [[email protected]]
# http://ruby-talk.com/41583
# But I see two potential problems that make not consistent with the
# original ruby command:
# 1) it takes only one argument

# code by Hee-Sob Park - posted here:
# http://ruby-talk.com/10006
def system(command)
#
http://msdn.microsoft.com/library/en-us/vccore98/html/_crt_system.2c_._wsystem.asp
Win32API.new("crtdll", "system", ['P'], 'L').Call(command)
end

# MENON Jean-Francois [[email protected]]
# http://ruby-talk.com/41583
# But I see two potential problems that make not consistent with the
# original ruby command:
# 1) it always set "$?" variable to false

# code by Hee-Sob Park - posted here:
# http://ruby-talk.com/10006
def `(command)
#
http://msdn.microsoft.com/library/en-us/vccore98/HTML/_crt__popen.2c_._wpopen.asp
popen = Win32API.new("crtdll", "_popen", ['P','P'], 'L')
pclose = Win32API.new("crtdll", "_pclose", ['L'], 'L')
fread = Win32API.new("crtdll", "fread", ['P','L','L','L'], 'L')
feof = Win32API.new("crtdll", "feof", ['L'], 'L')
saved_stdout = $stdout.clone
psBuffer = " " * 128
rBuffer = ""
f = popen.Call(command,"r")
while feof.Call( f )==0
l = fread.Call( psBuffer,1,128,f )
rBuffer += psBuffer[0..l]
end
pclose.Call f
$stdout.reopen(saved_stdout)
rBuffer
end
 
T

Tobias Reif

Chris,

thank you very much for the tip! It works.

I appreciate any further feedback. Does the below work on "all" OSs and
with most recent versions of Ruby? Mac, BSD, 1.8?
To anyone else replying: please CC me. TIA :)

Below is what I have now, I plan on including it in
http://www.pinkjuice.com/howto/vimxml/
http://www.pinkjuice.com/howto/vimxml/setup.xml

######################################################################

# based on
# www.ruby-talk.org/9739 and
# www.ruby-talk.org/10006
# seems to be not necessary for Ruby 1.7.2+, see
# http://www.rubygarden.org/article.php?sid=240
# please feed back improvements:
# tobiasreif pinkjuice com

require 'Win32API'
require 'rbconfig'

alias oldBackquote `

def `(command)
if Config::CONFIG["arch"] =~ /win/
popen = Win32API.new("crtdll", "_popen", ['P','P'], 'L')
pclose = Win32API.new("crtdll", "_pclose", ['L'], 'L')
fread = Win32API.new("crtdll", "fread", ['P','L','L','L'], 'L')
feof = Win32API.new("crtdll", "feof", ['L'], 'L')
saved_stdout = $stdout.clone
psBuffer = " " * 128
rBuffer = ""
f = popen.Call(command,"r")
while feof.Call( f )==0
l = fread.Call( psBuffer,1,128,f )
rBuffer += psBuffer[0..l]
end
pclose.Call f
$stdout.reopen(saved_stdout)
rBuffer
else
oldBackquote command
end
end

# test:

tidy_version_command_abs = '\for-programs\use\tidy\tidy.exe -v'
puts `#{tidy_version_command_abs}`

tidy_version_command = 'tidy -v'
puts `#{tidy_version_command}`

windows_version_command = 'ver'
puts `#{windows_version_command}`

ruby_version_command = 'ruby -v'
puts `#{ruby_version_command}`

java_version_command = 'java -version'
puts `#{java_version_command}`

xmllint_version_command = 'xmllint --version'
puts `#{xmllint_version_command}`

temp_path_command = 'echo %temp%'
puts `#{temp_path_command}`

######################################################################

Tobi
 
T

Tobias Reif

P.S.

I moved the line
require 'Win32API'
inside
if Config::CONFIG["arch"] =~ /win/
Now it also works on Linux.

Tobi
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top