Can a ruby script perform a chdir on win xp?


#1

I want to run a ruby script, and end up in a different directory.
Possible?

All of the obvious approaches (%x, ``, system()) can change
directories, but only for their own process, once the script ends,
you’re right were you started.

For those who wonder ‘why?’… I have a Rake task that sets up new
projects by building a project directory tree, and a couple of stub
files. When I run it, I want to end up inside one of the project
dirs.


#2

On 4/29/06, Park H. removed_email_address@domain.invalid wrote:

Possible?

Bill G. (aka aGorilla)
The best answer to most questions is “it depends”.

There was the same question in ruby-talk
and the
answer(http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/68095) is
make test.bat like this:

I was hoping for a simpler solution, but that’ll work.
Thanks much.


#3

Hi,

directories, but only for their own process, once the script ends,

There was the same question in ruby-talk
and the
answer(http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/68095)
is
make test.bat like this:

@rem = '–Ruby–
@echo off
if “%TEMP%” == “” (
echo TEMP not set
goto exit 2>nul
)
SET ARG=%1
if “%1” == “” (
SET ARG=nil
)
set TMP_BAT_FILE=%TEMP%\TMPBAT_%RANDOM%.bat

:exec
ruby -x -S Test.bat %TMP_BAT_FILE% %1 %2 %3
goto endofruby
@rem ';
#!ruby

ruby code here

write out Windows shell commands to the ARGV[0] filename

File.open(ARGV[0],“w”) { |f|
f.puts(‘cd \download’)
}
END
:endofruby
@echo off
if exist %TMP_BAT_FILE% call %TMP_BAT_FILE%
del %TMP_BAT_FILE% 2> nul
set TMP_BAT_FILE=


#4

Robert K. wrote:

2006/4/29, Bill G. removed_email_address@domain.invalid:

I was hoping for a simpler solution, but that’ll work.
Thanks much.

I don’t know why this complex stuff was suggested. Dir.chdir does the
job - or am I missing something?

Dir.chdir doesn’t change your directory in the shell it’s running in
after the program has finished. That’s what he was after I think.

Regards,

Dan


#5

2006/4/29, Bill G. removed_email_address@domain.invalid:

I was hoping for a simpler solution, but that’ll work.
Thanks much.

I don’t know why this complex stuff was suggested. Dir.chdir does the
job - or am I missing something? Note also the nice block form:

http://ruby-doc.org/core/classes/Dir.html#M001148

robert


#6

On Apr 29, 2006, at 3:44 PM, Lloyd Z. wrote:

Unfortunately, no program running in any language can change the
directory in the shell it’s running in, after the program has finished
… assuming that the program is invoked as a process that is separate
from that of the shell (which is how ruby is invoked).

This is a function of how the operating system is designed. It’s true
for windows-based systems as well as unix-like systems.

I probably just don’t understand what you meant, but what about the
“cd” program? Is that somehow not separate from the shell?

– Elliot T.


#7

Oops. it seems:

man cd

DESCRIPTION
Shell builtin commands are commands that can be executed within
the run-
ning shell’s process.

On Apr 29, 2006, at 3:51 PM, Elliot T. wrote:

– Elliot T.


#8

Daniel B. removed_email_address@domain.invalid writes:

Robert K. wrote:

2006/4/29, Bill G. removed_email_address@domain.invalid:

I was hoping for a simpler solution, but that’ll work.
Thanks much.
I don’t know why this complex stuff was suggested. Dir.chdir does the
job - or am I missing something?

Dir.chdir doesn’t change your directory in the shell it’s running in
after the program has finished. That’s what he was after I think.

Unfortunately, no program running in any language can change the
directory in the shell it’s running in, after the program has finished
… assuming that the program is invoked as a process that is separate
from that of the shell (which is how ruby is invoked).

The shell maintains its own idea of the current working directory. When
a program is invoked, the current working directory can be changed in
that program’s environment, but when the program exits, you are back in
the shell’s environment, with its own idea of the current working
directory.

If you invoke a .bat or .cmd script, that is run by the winxp command
shell itself, and those programs can therefore change the shell’s idea
of the current working directory. But once you invoke a .exe, you are
in a separate program environment that has no way to change the
properties of the shell.

This is a function of how the operating system is designed. It’s true
for windows-based systems as well as unix-like systems.


#9

Elliot T. removed_email_address@domain.invalid writes:

I probably just don’t understand what you meant, but what about the
“cd” program? Is that somehow not separate from the shell?

“cd” is not a program. It’s a command that is implemented within the
shell. In other words, the shell itself interprets the “cd” (or
“chdir”, which is equivalent), and it causes the shell to change its
idea of the current working directory.


#10

On 4/29/06, Lloyd Z. removed_email_address@domain.invalid wrote:

Dir.chdir doesn’t change your directory in the shell it’s running in
the shell’s environment, with its own idea of the current working
directory.

If you invoke a .bat or .cmd script, that is run by the winxp command
shell itself, and those programs can therefore change the shell’s idea
of the current working directory. But once you invoke a .exe, you are
in a separate program environment that has no way to change the
properties of the shell.

This is a function of how the operating system is designed. It’s true
for windows-based systems as well as unix-like systems.

Thanks for the detailed answer.

That was pretty much my thinking on it, but I was doing some wishful
thinking that there was some clever way to get around it. The batch
file approach will work, but it’s just not as elegant as I’d like.
Was also wondering if there was some Win32 call that might pull it
off.


#11

Lloyd Z. removed_email_address@domain.invalid writes:

I don’t know why this complex stuff was suggested. Dir.chdir does the

Well, back in the days of MS-DOS, an executable program could go through
your system’s memory and find the place where the shell stored its idea
of the current working directory, which the program could then change.
But with the OS’s that are built on top of the winnt architecture, those
days are gone, as far as I know.

Actually, here’s a sort-of clever way to get ruby to change your shell’s
idea of the current working directory. However, it requires a wrapper
script that needs to be sourced by your shell.

  • Create a file that contains the following commands:

    Under unix-like systems, the file can have any name
    (for example, “ruby-prog”), and it should contain this
    line:

    cd my-ruby-prog.rb

    Under windows-based os’s, make this a .bat or .cmd file
    (for example, “ruby-prog.cmd” or “ruby-prog.bat”), and
    make it contain these two lines:

    @echo off
    for /f “usebackq” %%i (my-ruby-prog.rb) do cd %i

  • In your ruby program, when it is ready to exit, issue
    these instructions:

    puts cwd
    exit(0)

    … where the “cwd” variable contains the name of the
    directory which ruby wants the shell to change to
    after the ruby program exits.

  • Then, invoke the program as follows:

    Under unix-like systems, type this:

    source ruby-prog # csh-type shells

    or

    . ruby-prog # sh-type shells

    Under windows-based systems, just type this:

    ruby-prog


#12

Lloyd Z. removed_email_address@domain.invalid writes:

[ … ]

Correction:

@echo off
for /f "usebackq" %%i (`my-ruby-prog.rb`) do cd %i
  for /f "usebackq" %%i (`my-ruby-prog.rb`) do cd %%i

#13

“Bill G.” removed_email_address@domain.invalid writes:

for windows-based systems as well as unix-like systems.

Thanks for the detailed answer.

That was pretty much my thinking on it, but I was doing some wishful
thinking that there was some clever way to get around it. The batch
file approach will work, but it’s just not as elegant as I’d like. Was
also wondering if there was some Win32 call that might pull it
off.

Well, back in the days of MS-DOS, an executable program could go through
your system’s memory and find the place where the shell stored its idea
of the current working directory, which the program could then change.
But with the OS’s that are built on top of the winnt architecture, those
days are gone, as far as I know.


#14

“Bill G.” removed_email_address@domain.invalid writes:

I like the look of it, but it’s not working here:

c:\work\active\apps>cdir.bat
(cdir.rb) was unexpected at this time.

Hmm … I wonder if this needs to run in a .cmd file instead of a .bat
file. Under winxp, it works for me in a .cmd file exactly as written.
Maybe if you rename your file to be cdir.cmd … ???


#15

On 4/29/06, Lloyd Z. removed_email_address@domain.invalid wrote:

Lloyd Z. removed_email_address@domain.invalid writes:

[ … ]

Correction:

@echo off
for /f "usebackq" %%i (`my-ruby-prog.rb`) do cd %i
  for /f "usebackq" %%i (`my-ruby-prog.rb`) do cd %%i

I like the look of it, but it’s not working here:

c:\work\active\apps>cdir.bat
(cdir.rb) was unexpected at this time.

cdir.bat:

@echo off
for /f “usebackq” %%i (cdir.rb) do cd %%i

cdir.rb:

cwd = ‘\windows’
puts cwd
exit(0)


#16

“Bill G.” removed_email_address@domain.invalid writes:

file. Under winxp, it works for me in a .cmd file exactly as written.
Maybe if you rename your file to be cdir.cmd … ???

Same results. Deleted the .bat file, and called it explicitly
(cdir.cmd) to make sure.

Actually, I had to do this:

\path\to\ruby.exe cdir.rb instead of just cdir.rb

I accidentaly copied and pasted the command line that I posted here from
an earlier version that didn’t work. I’m sorry for the confusion.

But if even this doesn’t work for you, then someone more familiar with
windows will have to jump in here. Unfortunately, I spend most of my
time in unix-based systems and I’m not sure where to go from here.

But I’m sure that this is do-able in windows, one way or the other.


#17

On 4/29/06, Lloyd Z. removed_email_address@domain.invalid wrote:

\path\to\ruby.exe cdir.rb instead of just cdir.rb

I accidentaly copied and pasted the command line that I posted here from
an earlier version that didn’t work. I’m sorry for the confusion.

But if even this doesn’t work for you, then someone more familiar with
windows will have to jump in here. Unfortunately, I spend most of my
time in unix-based systems and I’m not sure where to go from here.

Nope, that didn’t help (yet). Not sure that ‘unfortunately’ applies
here btw :wink:

But I’m sure that this is do-able in windows, one way or the other.

I’m inclined to agree, and thanks much for trying. If nothing else,
you gave me food for thought, and a couple of search terms.

Already found some new toys, had never heard of pushd or popd, handy
to have around.


#18

On 4/29/06, Lloyd Z. removed_email_address@domain.invalid wrote:

Maybe if you rename your file to be cdir.cmd … ???

Same results. Deleted the .bat file, and called it explicitly
(cdir.cmd) to make sure.


#19

Hi,
A simple but not so pleasing method is:

Dir::chdir(“c:\”)
system(“cmd”)

this will spawn a new command line with the inherited path.

Bill Stevens

Bill G. wrote:

I want to run a ruby script, and end up in a different directory.
Possible?

All of the obvious approaches (%x, ``, system()) can change
directories, but only for their own process, once the script ends,
you’re right were you started.

For those who wonder ‘why?’… I have a Rake task that sets up new
projects by building a project directory tree, and a couple of stub
files. When I run it, I want to end up inside one of the project
dirs.


#20

On 4/30/06, Bill G. removed_email_address@domain.invalid wrote:

c:\work\active\apps>cdir.bat
(cdir.cmd) to make sure.

But I’m sure that this is do-able in windows, one way or the other.

I’m inclined to agree, and thanks much for trying. If nothing else,
you gave me food for thought, and a couple of search terms.

a slightly less trickey way to do it (and apologies if this was already
proposed, I’ve been kinda skimming this thread up til now) would be to
call
your ruby program from a cmd file, and call another cmd file right
after.
then your ruby program could re-write the second cmd file.

like this:

doit.cmd contents:
ruby myprog.rb
followup.cmd

followup.cmd contents (written by myprog.rb):
cd c:\whatever\

…pretty sure this would work, if you can’t get the originally proposed
command line magic to work. It’d work as .bat files too, so you could
use
it in Win98 or DOS or whatever.

Cheers

;Daniel