Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
    
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 Jul 29 '11 at 0:59
    
Just to be clear this is referring to windows batch-files. – Greg Jul 30 '11 at 9:02
    
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 Jul 30 '11 at 9:03
    
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 Jul 30 '11 at 15:38
    
Yes, sorry, I realise I wasn't clear (although I think 'batch-file' was a hint :-p) – Greg Aug 1 '11 at 0:20
up vote 16 down vote accepted

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.

share|improve this answer
1  
Ah, so single ampersand is the equivalent of semi-colon in sh. That's perfect. (and a reference: ss64.com/nt/syntax-conditional.html) – Greg Jul 30 '11 at 9:30
5  
It'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 – grawity Jul 30 '11 at 12:46

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.

share|improve this answer
    
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 Jul 30 '11 at 9:06
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. – grawity Jul 30 '11 at 12:45

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
share|improve this answer
    
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 Jul 30 '11 at 9:08
    
As BillP3rd pointed out the equivalent of ';' in batch-files is '&'. – Greg Jul 30 '11 at 9:33
    
Ah, sorry. Your use of forward slashes made me think it was UNIX. – bahamat Jul 30 '11 at 16:57

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.

share|improve this answer

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.

share|improve this answer

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.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .