tags:

views:

130

answers:

6

I want to execute a command like 'git tag -l' inside a directory /home/user/git/app/ but I am actually in /home/user. How can I do that in bash without changing my working directory?

So NOT:

cd /home/user/git/app && git tag -l

because that actually changes my working directory and have to do 'cd /home/user' again.

A: 

try to use

cd -

after everything is done. This command is used to go back to your last working directory.

ibread
A: 

One way to do it (which probably isn't the cleanest) is

echo "`cd /home/user/git/app && git tag -l`"

The backticks start a subshell, so that the chagne to the working directory won't affect the shell you're executing it from. The echo command is required to prevent the output being considered a command!

I would have reservations about using this in an automated/important environment, though - I expect it's almost certain that some particular output of the embedded command would cause Bad Things to happen. If you're just using it in some quick script to make things easier for yourself that's OK, but if it needs to be robust I'm sure there are proper ways of doing this. :-)

...And as Dennis points out, one is here.

Andrzej Doyle
See **Jefromi's** answer.
Dennis Williamson
+3  A: 

If the command in question is always going to be a git command, you should just use the --git-dir and --work-tree options to tell git what to do! (Or if you're doing this a lot over the course of a script, set the variables GIT_DIR and GIT_WORK_TREE to the appropriate paths)

If this is a general question, I believe Andrzej has a start on the best suggestion: use a subshell. The proper way to start a subshell, though, is to use parentheses, not to use command substitution (unless you actually want to capture the output):

( cd $dir && run_command )

The other solution, as suggested by Felix and ibread, will of course work, but do be careful - if the command you're executing is perhaps a shell function, then it could also cd, and change the effect of the cd - at the end. The safest thing in the general case is to store the current directory in a variable first.

Jefromi
It is a git command mostly, so it is both. Thanks for the hint on the GIT_DIR!
primeminister
This is how all of the scripted git commands work internally (at least in current git) - they inherit the settings for GIT_DIR and GIT_WORK_TREE from the calling git command, and then git commands they subsequently call inherit it from them.
Jefromi
+1  A: 

You might want to do something like (cd /home/user/git/app && git tag -l). This spawns a new shell and executes the commands in the shell without changing your shell. You can verify this by executing the following:

$ echo $OLDPWD
/Users/daveshawley
$ (cd / && ls)
...
$ echo $OLDPWD
/Users/daveshawley
D.Shawley
I'd still suggest using ``, in case you're using a variable for the directory, so it may not exist, and the command would abort (or worse, mess things up).
Jefromi
+8  A: 

Just bracket the whole thing. That will run it in a subshell which can go to any directory and not affect your 'current working' one. Here's an example.

noufal@sanctuary% pwd
/tmp/foo
noufal@sanctuary% (cd ../bar && pwd && ls -a )
/tmp/bar
./  ../
noufal@sanctuary% pwd
/tmp/foo
noufal@sanctuary%            
Noufal Ibrahim
+2  A: 

Here is another solution: use pushd to change directory, then popd to return:

pushd /home/user/git/app && git tag -l; popd
Hai Vu
When you want to run a command somewhere else without changing the working directory, `pushd`/`popd` are definitely the way to go.
bta
Dennis Williamson
The one problem with the `pushd`/`popd` approach is that it can lose information such as the `OLDPWD` environment variable. You are better off not stomping the user's environment and just run in a subshell.
D.Shawley
@D.Shawley: Yes, you are correct.@Dennis Williamson: I am a little confused, would you please explain?
Hai Vu
Dennis Williamson
@Dennis Williamson: what an eye opener. Thank you.
Hai Vu