Temporarily change directory for single batch-file command

20

3

In shell-scripting if I need to run a command from a directory I can us a subshell to ensure I return to the original context:

(cd temporary/new/directory ; command)
# now I am still in original directory

Can this be done in Windows batch-files (or cmd-files)

Doing the same in batch-files leaves me in the new directory.

I can do:

pushd temporary\new\directory && command && popd

But the popd is dependent on the success of command.

Any ideas?

Greg

Posted 2011-07-29T00:12:14.460

Reputation: 865

How are you invoking your "batch-file" or "cmd-file"? If you put a cd command into a shell script and execute that script (not source it), the current working directory of the calling shell will not change. – garyjohn – 2011-07-29T00:59:52.103

Just to be clear this is referring to windows batch-files. – Greg – 2011-07-30T09:02:28.053

Its a script which runs a bunch of commands in different parts of a directory tree. Some of the commands only operate on the current-directory. Returning to the original directory helps simplify the data that drives the script. Are you suggesting making a separate batch-file for each directory that i need to make calls in? – Greg – 2011-07-30T09:03:52.963

As I recall, you referred to shell scripts and didn't mention Windows in your original question, so I incorrectly assumed that you were using a Unix-like system. Now I understand. – garyjohn – 2011-07-30T15:38:54.320

Yes, sorry, I realise I wasn't clear (although I think 'batch-file' was a hint :-p) – Greg – 2011-08-01T00:20:32.617

Answers

22

If you do:

pushd \windows && foobar && popd

you'll be left (as you state) in the \windows folder. Try:

pushd \windows & foobar & popd

and you should find yourself back where you started.

BillP3rd

Posted 2011-07-29T00:12:14.460

Reputation: 5 353

1

Ah, so single ampersand is the equivalent of semi-colon in sh. That's perfect. (and a reference: http://ss64.com/nt/syntax-conditional.html)

– Greg – 2011-07-30T09:30:44.477

6It's good to remember that cd/pushd sometimes fails (if the directory doesn't exist, for example). pushd \windows && (foobar & popd) may be more reliable – user1686 – 2011-07-30T12:46:54.043

16

By default, Windows batch files are run in the parent shell's context (which is unusual for Unix users, where an explicit source is needed, but was the only possibility in MS-DOS). This means directory changes and environment variables affect the original interactive shell too.

Put setlocal at the top of your script to make it run in its own context – you can safely use cd inside the script then.

user1686

Posted 2011-07-29T00:12:14.460

Reputation: 283 655

Thanks, This sounds like what I need - I'll check it when I get access to a Windows machine. Would that affect sub-commands using parentheses? – Greg – 2011-07-30T09:06:44.053

1@Greg: It seems that ( ) only group commands together, but still run them in the parent context. (setlocal & cd foo & bar) will not work; instead pushd foo && (bar & popd) would be needed. – user1686 – 2011-07-30T12:45:33.280

4

As grawity previously mentioned, pushd \windows && (foobar & popd) would work better than pushd \windows & foobar & popd because the latter may fail if there is no such directory.

Also, using setlocal and endlocal allows you to have multiple local environments, so for example you could have:

setlocal

cd dir

command

endlocal

Now you would be back in your original directory.

Timtech

Posted 2011-07-29T00:12:14.460

Reputation: 177

3

You can use cd - to go back to the previous working directory. And use ; instead of &&, then the subsequent commands won't be dependent on the success of previous commands.

$ pwd
/etc
$ cd /var ; pwd ; cd -
/var
$ pwd
/etc

bahamat

Posted 2011-07-29T00:12:14.460

Reputation: 5 130

I've updated question to clarify I'm asking about windows batch/shell scripting. I know how to do it under a sh-like shell :) – Greg – 2011-07-30T09:08:05.347

As BillP3rd pointed out the equivalent of ';' in batch-files is '&'. – Greg – 2011-07-30T09:33:20.557

Ah, sorry. Your use of forward slashes made me think it was UNIX. – bahamat – 2011-07-30T16:57:55.080

1

I applaud grawity’s suggestion to put setlocal at the beginning of your batch script, but I would add the fact that you can have multiple, nested, setlocal / endlocal blocks, so a more relevant answer to the question might be

@echo off
setlocal
cddir1
  ...
setlocal
cddir2
command
endlocal
:: Now I am back indir1
  ...

And, of course, if you want the command to be executed only if the cd to dir2 is successful, say cddir2&&command.

Note that the setlocal / endlocal block creates a localized environment, so any variables that you set or change in such a block will revert to its previous value after the endlocal.

Scott

Posted 2011-07-29T00:12:14.460

Reputation: 17 653

0

You can save the current directory into a variable. Change and change back depending on the return value of the command. BTW, %CD% returns your current DIR.

surfasb

Posted 2011-07-29T00:12:14.460

Reputation: 21 453