Temporarily change directory for single batch-file command
Solution 1
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.
Solution 2
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.
Solution 3
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.
Solution 4
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
Solution 5
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
cd
dir1
...
setlocal
cd
dir2
command
endlocal
:: Now I am back in
dir1
...
And, of course, if you want the command to be executed only if the cd
to dir2
is successful, say cd
dir2
&&
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
.
Related videos on Youtube
Greg
Updated on September 18, 2022Comments
-
Greg almost 2 years
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?
-
garyjohn almost 13 yearsHow 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.
-
Greg almost 13 yearsJust to be clear this is referring to windows batch-files.
-
Greg almost 13 yearsIts 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?
-
garyjohn almost 13 yearsAs 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.
-
Greg almost 13 yearsYes, sorry, I realise I wasn't clear (although I think 'batch-file' was a hint :-p)
-
-
Greg almost 13 yearsThanks, 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 almost 13 yearsI'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 almost 13 yearsAh, so single ampersand is the equivalent of semi-colon in sh. That's perfect. (and a reference: ss64.com/nt/syntax-conditional.html)
-
Greg almost 13 yearsAs BillP3rd pointed out the equivalent of ';' in batch-files is '&'.
-
user1686 almost 13 years@Greg: It seems that
(
)
only group commands together, but still run them in the parent context.(setlocal & cd foo & bar)
will not work; insteadpushd foo && (bar & popd)
would be needed. -
user1686 almost 13 yearsIt'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 -
bahamat almost 13 yearsAh, sorry. Your use of forward slashes made me think it was UNIX.