From: Robert Klemme Date: 2010-02-09T16:52:53+09:00 Subject: Re: Working directory for external commands 2010/2/9 Duckz King_duckz : > Hello everyone, I've been searching on google for a while now but I > can't find any solution to my question. Basically I want to be able to > specify the working directory for any external command I might launch, > without using ugly globals :S > What I'm trying to write is a wrapper class for git. As a client, I want > to be able to write, for example: > > [code] > git = GitWrapper.new > puts git.status > [/code] > > and of course I don't want to know what's happening inside status(). > > In order to invoke git I'm doing `git status`, or `"c:/program > files/git/bin/sh.exe" -c "git status"`, depending on the OS and other > things. The problem is, backticks as well as %x, system and friends rely > on Dir.pwd, so in order to get a valid result from git I should do: > [code] > def status() >    Dir.chdir("some/dir") do >        return `git status` >    end > end > [/code] > which I'd rather avoid for its obvious fragility: > [code] > git = GitWrapper.new > a = Thread.new {10000.times do {Dir.chdir("some/other/dir"); > do_some_work(); `rm -rf '*'`}} > puts git.status() # OMG!!!!!111 > a.join > [/code] > > Any suggestions? The only safe way I can think of is to defer the chdir to a child process. The shortest form would be irb(main):006:0> s=`cd /tmp && exec pwd` => "/tmp\n" irb(main):007:0> (Using "git status" instead of "pwd" of course.) A Ruby solution would probably include IO.popen or popen3 and fork. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/