# Working directory for external commands

**URL:** <https://www.ruby-forum.com/t/working-directory-for-external-commands/183150>\
**Category:** Ruby\
**Created:** [February 9, 2010, 1:01am UTC](https://www.ruby-forum.com/t/working-directory-for-external-commands/183150 "2010-02-09T01:01:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![king\_duckz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/58f4c7/32.png) [@king\_duckz](https://www.ruby-forum.com/u/king_duckz)\
**Post date:** [February 9, 2010, 1:01am UTC](https://www.ruby-forum.com/t/working-directory-for-external-commands/183150/1 "2010-02-09T01:01:21Z")

</div>

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:

```auto
git = GitWrapper.new
puts git.status
```

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:

```auto
def status()
    Dir.chdir("some/dir") do
        return `git status`
    end
end
```

which I’d rather avoid for its obvious fragility:

```auto
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
```

Any suggestions?

---

<div class="post-metadata">

**Author:** ![king\_duckz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/58f4c7/32.png) [@king\_duckz](https://www.ruby-forum.com/u/king_duckz)\
**Post date:** [February 9, 2010, 1:57am UTC](https://www.ruby-forum.com/t/working-directory-for-external-commands/183150/2 "2010-02-09T01:57:37Z")

</div>

Duckz King\_duckz wrote:

> 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.

This doesn’t directly answer your question, but have you looked at Grit?

Best,  
–Â  
Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![king\_duckz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/58f4c7/32.png) [@king\_duckz](https://www.ruby-forum.com/u/king_duckz)\
**Post date:** [February 9, 2010, 9:04am UTC](https://www.ruby-forum.com/t/working-directory-for-external-commands/183150/3 "2010-02-09T09:04:35Z")

</div>

2010/2/9 Duckz King\_duckz [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> [/code]  
> return `git status`  
> [/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

---

<div class="post-metadata">

**Author:** ![king\_duckz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/58f4c7/32.png) [@king\_duckz](https://www.ruby-forum.com/u/king_duckz)\
**Post date:** [February 9, 2010, 11:51am UTC](https://www.ruby-forum.com/t/working-directory-for-external-commands/183150/4 "2010-02-09T11:51:59Z")

</div>

@Marnen Laibow-Koser:  
I didn’t hear of it, but from a quick look it seems to allow a much  
cleaner solution, I’ll look into that! Anyways, the global Dir problem  
has already occurred to me in other situations, and I’m still interested  
in finding a safe solution! I wonder why popen or system don’t allow an  
optional parameter to specify the working directory!

@Robert K.:  
Thanks for the hint, I guess I’ll follow that path to write an intial  
version, before looking in depth into Grit. Are there any issues with  
fork implementation on Windows in Ruby 1.9.1? Still, I find it a shame  
you can’t specify the cwd as a parameter (as in CreateProcess() on  
Windows for example, but I’m sure most OS have an equivalent).

---

<div class="post-metadata">

**Author:** ![king\_duckz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/58f4c7/32.png) [@king\_duckz](https://www.ruby-forum.com/u/king_duckz)\
**Post date:** [February 9, 2010, 2:38pm UTC](https://www.ruby-forum.com/t/working-directory-for-external-commands/183150/5 "2010-02-09T14:38:27Z")

</div>

Albert S. wrote:

> Duckz King\_duckz wrote:
> 
> > I guess I’ll follow that path to write an intial  
> > version, before looking in depth into Grit.
> 
> BTW, there are two gems: ‘grit’ and ‘git’. I don’t know what’s the  
> difference between them.

Grit is pure Ruby. I think the git gem is just a wrapper.

Best,  
–Â  
Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![king\_duckz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/58f4c7/32.png) [@king\_duckz](https://www.ruby-forum.com/u/king_duckz)\
**Post date:** [February 9, 2010, 2:22pm UTC](https://www.ruby-forum.com/t/working-directory-for-external-commands/183150/6 "2010-02-09T14:22:25Z")

</div>

Duckz King\_duckz wrote:

> I guess I’ll follow that path to write an intial  
> version, before looking in depth into Grit.

BTW, there are two gems: ‘grit’ and ‘git’. I don’t know what’s the  
difference between them.
