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

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 :slight_smile:

… 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 :slight_smile:

Tobi

···


http://www.pinkjuice.com/

Hello,

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

···

on Sep.03,2003 17:58:26, tobiasreif@pinkjuice.com wrote:

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 :slight_smile:

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.Nakamura usa@osb.att.ne.jp

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 [Jean-Francois.MENON@meteo.fr]

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 [Jean-Francois.MENON@meteo.fr]

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

Chris
http://clabs.org/blogki

Hi

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
:slight_smile:

Solution A:

First of all: Thanks for replying!

cmd = ‘\for-programs\use\tidy\tidy.exe -v’
command.com /c #{cmd}

Tried that already (see “def shell command” in the original post),
doesn’t work on Windows ME.

########## nakamura ##########
#Solution A:
cmd = ‘\for-programs\use\tidy\tidy.exe -v’
puts command.com /c #{cmd}

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

···

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

C:\del>ruby nakamura

C:\del>

No output.

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

Does your code work for you, on a Win9* (Windows ME) box?

This really is a thorny problem … I tried a lot already. I need code
which actually works on Win9* boxen.

Tobi


http://www.pinkjuice.com/

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 :slight_smile:

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


http://www.pinkjuice.com/

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,

···

on Sep.03,2003 18:29:10, tobiasreif@pinkjuice.com wrote:

U.Nakamura usa@osb.att.ne.jp

P.S.

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

Tobi

···


http://www.pinkjuice.com/

Hi

U.Nakamura wrote:

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 :frowning:

Tobi

···


http://www.pinkjuice.com/

Hello,

In message “Re: how to get the output of commands which contain backslashes?”

Your code

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

works on XP?

It’s not work. Sorry, I mistook.
But

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

This works on my XP box.

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

Yes.
\f and \t is interpreted as special sequence.
So, we need to escape them.
But, \u is interpreted “as is”.

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 :frowning:

Now I can test on Win98 box at all.
To a strange thing (but as your report), Solution B’ did not
work.
But, on my Win98 box, Solution A worked.

BTW, if you want to know what is happens, try
command.com /c echo SOME TEST COMMAND LINE

Regards,

···

on Sep.03,2003 19:01:01, tobiasreif@pinkjuice.com wrote:

U.Nakamura usa@osb.att.ne.jp