1

I have a batch file that outputs a path. How can I use the batch file in Windows cmd to change the current directory?

What have I tried:

F:\>cd my-path.bat
The system cannot find the path specified.

F:\>cd (my-path.bat)
The system cannot find the path specified.

F:\>my-path.bat | cd
F:\
The process tried to write to a nonexistent pipe.

my-path.bat content:

@ECHO OFF

@ECHO F:\MyPath\
  • 2
    You might try setting it to an environment variable – Chipster Sep 15 at 22:09
  • 1
    @Daniil Palii I rejected you edit suggestion to my answer because the second part made it non-functional. Because the cd command was inside setlocal ... endlocal its effect would be lost when the script ends. The first part would be fine: the main reason I did it the way I did was that for a "more substantial" original script, the if line can be dropped in at the beginning without affecting the rest of the script. Using ) else ( ... ) as you suggested would nest the rest of the script unnecessarily. [cont] – TripeHound Sep 16 at 12:23
  • 1
    [cont] However, using parentheses for the "then" block, and putting cd F:\mypath and goto :eof on separate lines would be fine, and I did in fact toy with doing it like that. – TripeHound Sep 16 at 12:25
4
for /f "delims=" %d in ('my-path.bat') do cd /d "%~d"

Note: In a batch file you have to replace % by %%

| improve this answer | |
  • 1
    Looks terrible and unusable but it works, thank You. – Daniil Palii Sep 15 at 14:55
  • 3
    @DaniilPalii then you should switch to PowerShell, which has more elegant ways to handle such tasks. there you could just cd (& ".\my-bat.bat") – SimonS Sep 15 at 14:57
  • @SimonS, I like to have universal batch files to use it also in cmd and PowerShell, but You are right. – Daniil Palii Sep 15 at 15:02
  • @SimonS, in Powershell I can type also cd (my-path) and my-path | cd – Daniil Palii Sep 15 at 15:04
3

For different drivers you need /d in your cd command

If your folder/path/name have any space/special character, use “double-quotes” too

@echo off 

echo\"F:\path to your folder"

:: or add/replace echo\"F:\path to your folder" to cd /d :: 
cd /d "F:\path\to\folder"

An alternative would be to get the output in a loop, where the bat would not be changed, just the command line...

for /f tokens^=* %i in ('^<con: "my-path.bat"')do cd/d "%~i"
  • Remembering that loop variables %i in bat are %%i:
for /f tokens^=* %%i in ('^<con: "my-path.bat"')do cd/d "%%~i"

  • You can use arguments (%*) to variable run your command:
@echo off 

<con: call %* "F:\path to your folder" 2>nul || echo\"F:\path to your folder"

The 2>nul suppression any possible error, and if the last command do not return 0, one simple echo will take action...

Using argument in your bat:

my-path.bat cd /d

| improve this answer | |
  • @It_Wasn't_Me, what means "echo\" with a slash? I don't see it in the documentation. – Daniil Palii Sep 15 at 15:32
  • 1
    @DaniilPalii is the same echo( | echo; | echo[ | echo= | echo. , just prevent echo on ... see echo /? in your prompt.. – It Wasn't Me Sep 15 at 15:35
2

Why not simply change your Batch file to:

@echo off

cd F:\MyPath\
| improve this answer | |
  • I need this batch also in other cases and don't want to copy the code. – Daniil Palii Sep 15 at 14:51
  • I only understood that you wanted to use this for the F:\MyPath\, but happy you found out how to achieve this. – LeRouteur Sep 17 at 6:55
1

Building on LeRouteur's answer, the following might be a useful compromise:

@echo off
if "%~1" == "." cd /d F:\mypath && goto :eof
echo F:\mypath

Running just my-path will echo the path, as it currently does, but running my-path . (i.e. with a single full-stop as a parameter) will change to that path.

If you dislike having the path entered twice, this can be avoided by using an environment variable, but to do so "cleanly" (without polluting your existing environment) needs a little thought:

@echo off
setlocal
set "MYPATH=F:\mypath"
if "%~1" == "." (
    endlocal && cd /d "%MYPATH%"
    goto :eof
)
echo "%MYPATH%"

The use of setlocal means any changes to the environment (e.g. MYPATH) will only be made locally: running endlocal or reaching the end of the batch-file will revert to the original environment (see setlocal /? and endlocal /?).

Using setlocal is very common in batch-files so that any environment variables they use/change don't "pollute" the main environment. The problem is that the current directory is part of what is localized: if you run cd while setlocal is in effect, you will return to your starting directory when the script exits.

One solution is to put the endlocal and cd commands on the same line. The way batch-files are parsed means that the evaluation of MYPATH happens while the environment is still "local" (so it still has the right value), but the execution of the cd command (using the value that was obtained in the first pass) doesn't happen until after endlocal has executed, meaning the directory will be changed when it returns to the command-line.

The way I define MYPATH, and use its value (enclosed in double-quotes) allows for the path to contain spaces. Perhaps not necessary here, but a good habit to get into when writing batch-files.

As a final option, you could replace cd /d with pushd. The latter "pushes" the current directory onto a stack before changing to the new one (see pushd /?). When you are finished doing whatever you need to do in MYPATH you can then run popd to return to whichever directory you originally ran my-path . from.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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