Temporarily change directory for single batch-file command

28,141

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
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:
28,141

Related videos on Youtube

Greg
Author by

Greg

Updated on September 18, 2022

Comments

  • Greg
    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
      garyjohn almost 13 years
      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.
    • Greg
      Greg almost 13 years
      Just to be clear this is referring to windows batch-files.
    • Greg
      Greg almost 13 years
      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?
    • garyjohn
      garyjohn almost 13 years
      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.
    • Greg
      Greg almost 13 years
      Yes, sorry, I realise I wasn't clear (although I think 'batch-file' was a hint :-p)
  • Greg
    Greg almost 13 years
    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
    Greg almost 13 years
    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
    Greg almost 13 years
    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
    Greg almost 13 years
    As BillP3rd pointed out the equivalent of ';' in batch-files is '&'.
  • user1686
    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; instead pushd foo && (bar & popd) would be needed.
  • user1686
    user1686 almost 13 years
    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
  • bahamat
    bahamat almost 13 years
    Ah, sorry. Your use of forward slashes made me think it was UNIX.