I am trying to make a bat file to sync a folder. I couldn't install WASL yet, so for now, rsync is not an option.
I wrote below code as neat as possible. Please check why it is not working? Note: On notepad++, On Encoding Menu, "UTF8" is chosen by default. And I tried to click "Convert to UTF8"; nothing happened.
Please Help!
CHCP 65001
REM @ECHO OFF
REM GLOBALS
SET V_PF=\\10.0.0.222\kalite_dokumanlar\
SET V_PT=C:\me\desk\KALİTE\
REM INIT
GOTO:F_MAIN
REM FUNCTIONS
:F_SYNC
SETLOCAL ENABLEDELAYEDEXPANSION
SET V_IN=%~1
robocopy "%V_PF%%V_IN%\" "%V_PT%%V_IN%\" /MIR
ENDLOCAL
EXIT /B 0
REM MAIN
:F_MAIN
call:F_SYNC "DESTEK"
call:F_SYNC "MÜŞTERİ ve TEDARİK"
call:F_SYNC "SİSTEM"
call:F_SYNC "ÜRETİM"
REM SAVE WITH NOTEPAD++ ENCODED UTF8 WITHOUT BOM
see the code at github
The directories synchronization task can be done with the following batch file:
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
@REM Get the current code page and remember it with the environment variable InitialCodePage.
FOR /F "tokens=*" %%I IN ('%SystemRoot%\System32\chcp.com') DO FOR %%J IN (%%I) DO SET /A "InitialCodePage=%%J" 2>NUL
@REM Change the code page to UTF-8.
%SystemRoot%\System32\chcp.com 65001 >NUL
@REM GLOBALS
SET "V_PF=\\10.0.0.222\kalite_dokumanlar\"
SET "V_PT=C:\me\desk\KALİTE\"
@REM INIT
GOTO:F_MAIN
@REM FUNCTIONS
:F_SYNC
SET "V_IN=%~1"
@REM /NDL /NFL: NO LOGS = NO GARBAGE CHARS CON:
@REM /NJH /NJS: NO VERBOSE START-END
@REM /R:3: LIMIT RETRY
@REM /W:10: WAIT ON ERROR
%SystemRoot%\System32\robocopy.exe "%V_PF%%V_IN%" "%V_PT%%V_IN%" /MIR /R:3 /W:10
EXIT /B 0
@REM MAIN
:F_MAIN
CALL :F_SYNC "DESTEK"
CALL :F_SYNC "MÜŞTERİ ve TEDARİK"
CALL :F_SYNC "SİSTEM"
CALL :F_SYNC "ÜRETİM"
@REM Restore the initial code page.
%SystemRoot%\System32\chcp.com %InitialCodePage% >NUL
ENDLOCAL
@REM SAVE THAT CODE ENCODED UTF-8 WITHOUT BOM
The main correction is the removal of the backslashes at end of the source and destination paths on ROBOCOPY command line. %SystemRoot%\System32\robocopy.exe
is different to most other Windows commands. It interprets \
left to "
as an escape character for the double quote although no file/folder name can contain ever the character "
. For that reason it is strongly recommended to avoid a backslash at end of the source and destination path. If that is not possible because of source or destination path is the root directory of a drive, then either the path is not enclosed in "
at all or two backslashes are used at end of the path where the first backslash is escaping the second backslash to be interpreted as literal character. So working would be also:
%SystemRoot%\System32\robocopy.exe "%V_PF%%V_IN%\\" "%V_PT%%V_IN%\\" /MIR /R:3 /W:10
The usage of fully qualified file names for the executables reduces the number of file system accesses as the Windows command processor cmd.exe
does not need to search for the executables in this case. The batch file becomes additionally independent on the environment variables PATH
and PATHEXT
with using fully qualified file names.
The commands SETLOCAL ENABLEDELAYEDEXPANSION
and ENDLOCAL
inside the subroutine F_SYNC
are of no use and for that reason removed from the code. There are instead inserted a SETLOCAL at top and an ENDLOCAL at bottom which define completely the local execution environment required for this batch file. For more details about these two commands see my answer on
How to pass environment variables as parameters by reference to another batch file?
There is also inserted a space between the command CALL (argument 0) and the label (argument 1) to avoid two files system accesses with return value invalid file name. call:F_SYNC
is interpreted first as file name of an executable or script because of the missing space. This string is interpreted a second time by cmd.exe
just because of the invalid file name error returns and split up next into the two arguments call
and :F_SYNC
with detecting now that call
is an internal command of cmd
.