How to SET a dynamic folder path to a variable in Batch File?

I am writing a script to backup my mongoDB database. The backup is working fine but somehow I am unable to set folder location properly.

Below is my Script

@echo on
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a)
set print_time = %mydate%_%mytime%
set DIR=%print_time%
set DEST=D:\MongoDB\db_backup\%DIR%

mkdir %DEST%

mongodump -h -d DW -u [user]-p [password] -o %DEST%

The following line is note working.

set DIR=%print_time%

variable DIR is empty

Output from above Script


D:\MongoDB>For /F "tokens=2-4 delims=/ " %a in ('date /t') do (set 
mydate=%c-%a-%b )

D:\MongoDB>(set mydate=2019-06-24 )

D:\MongoDB>For /F "tokens=1-2 delims=/:" %a in ('time /t') do (set mytime=%a 

D:\MongoDB>(set mytime=04 )

D:\MongoDB>set print_time = 2019-06-24_04

D:\MongoDB>set DIR=

D:\MongoDB>set DEST=D:\MongoDB\db_backup\

D:\MongoDB>mkdir D:\MongoDB\db_backup\
A subdirectory or file D:\MongoDB\db_backup\ already exists.

  D:\MongoDB>mongodump -h -d DW -u [user]-p [password]-o 

As you can see the variable DIR is empty

2 answers

  • answered 2019-06-24 21:38 Ben Personick

    Try the following this works as expected for me.

    I suspect that you have a space in your original method, and this is just taking your code removing redundant parts and using Quotes around variables to make sure it isn't happening.

    SET "_UN=YourUserName"
    SET "_PW=YourPassword"
    SET "_MongoDBIPPort="
    SET "_MongoDB=DW"
    SET "_MongoBackupRoot=D:\MongoDB\db_backup"
    FOR /F "Tokens=1-7 delims=MTWFSmtwfsouehrandit:-\/. " %%A IN ("%DATE% %TIME: =0%") DO (
        FOR /F "Tokens=2-4 Skip=1 Delims=(-)" %%a IN ('ECHO.^| DATE') DO (
            SET "%%~a=%%~A" & SET "%%~b=%%~B" & SET "%%~c=%%~C" & SET "HH=%%~D" & SET "Mn=%%~E" & SET "SS=%%~F" & SET "Ms=%%~G"
    SET "_PrintTime=%yy%-%mm%-%dd%_%HH%.%Mn%"
    ECHO(_PrintTime = "%_PrintTime%"
    SET "_Dest=%_MongoBackupRoot%\%_PrintTime%"
    ECHO(Dest Directory = "%_Dest%"
    IF NOT EXIST "%_Dest%" (
        MD "%_Dest%"
    mongodump -h %_MongoDBIPPort% -d %_MongoDB% -u %_UN% -p %_PW% -o "%_Dest%"

    As your original code did not give me the issue you encountered, it again leads to to believe there may have some errant spaces in your variable declarations or other non printable characters which I am not able to receive through Stack Exchange.

    Note: I changed the code to no longer rely on the date being a particular format so that the code will run the same on my machine as yours as I use a different date format then you do, so I felt it was better to post code which should work for either of us.

    Sorry looks like I left this up mid-edit when I rushed out yesterday, and did not post it at that time.

    Hope that helps! :)

  • answered 2019-06-25 11:08 Compo

    As per my comment…

    The main issue with your code is that you have not followed the guidance for the use of the Set command. Opening a Command Prompt window and entering set /?, should have been sufficient to learn how to use that command, from the output.

    Currently your variable is %print_time % not %print_time%, because spaces either side of the = are included in both the variables name and value. Effectively you need to change set print_time = %mydate%_%mytime% to set print_time=%mydate%_%mytime%.

    In addition, it is best practice to use quotation marks to protect spaces and other 'poison' characters in your strings. When it come to setting a variable, the recommended syntax is Set "VariableName=Variable Value", so you should be using, Set "print_time=%mydate%_%mytime%". Also although not necessary with the provided path, it is safer to enclose the variable %DIR% in quotation marks too, (this would mean that any change in the destination path, perhaps introducing spaces or ampersands, would not affect the rest of the code). You should therefore do that in your MkDir and mongodump command lines, thus:

    @Echo Off
    For /F "Tokens=2-4Delims=/ " %%A In ('Date /T')Do Set "MyDate=%%C-%%A-%%B"
    For /F "Delims=:" %%A In ('Time /T')Do Set "MyTime=%%A"
    Set "print_time=%MyDate%_%MyTime%"
    Set "DIR=%print_time%"
    Set "DEST=D:\MongoDB\db_backup\%DIR%"
    MkDir "%DEST%" 2>NUL
    mongodump -h -d DW -u [user] -p [password] -o "%DEST%"

    The methods you used in creating your date and time string is not very robust, because the results of Date and Time with their /T option are Locale/PC/User dependent. I would suggest you use a method which isn't, so offer a solution which uses RoboCopy instead. Additionally, the following defines only one variable in achieving your goal, instead of five:

    @Echo Off
    Set "DEST="
    For /F "Tokens=1-4Delims=/: " %%A In ('RoboCopy /NJH /L "\|" Null')Do If Not Defined DEST Set "DEST=D:\MongoDB\db_backup\%%A-%%B-%%C_%%D"
    If Not Defined DEST GoTo :EOF
    MD "%DEST%" 2>NUL
    mongodump -h -d DW -u [user] -p [password] -o "%DEST%"