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?
56 Answers
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.
2By 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.
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.
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 3I 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.
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.