Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

6 Answers 6

up vote 9 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
4  
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.