Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return value of a function to a function in batch script

This could possibly a duplicate of several questions out there in the SO, dostips and ss64. The research I've done point me to look out for _scope_ in functions. but my solutions is simple and straight forward but still problem exists

  1. what is really behind the SETLOCAL and ENDLOCAL
  2. How contextworkd in batch scripts ex (goto) 2>nul
  3. Why (goto) wrapped in braces (explained in dostips)

Here is the code i've written so far to copy file from one place to another. My Goals were:

  • Research the scope and contextof batch script
  • code reuse
    @echo off
    setlocal EnableDelayedExpansion
    goto :main

:main
    setlocal
    set _app=test
    set _base=C:/wamp64/www
    set _destination=!_base!/test
    set _source=%~dp0%/build
    set /A _flag=0

    echo *********************************************
    echo    Deploying in %~1 mode: %TIME%
    echo        Deploy path: !^_destination!
    echo *********************************************

    call :check !_base!, !_app!, _flag
    if !_flag!==0 (
        call :create !_base!, !_app!
    )
    xcopy "!_source!" "!_destination!" /D /C
    exit /b 0
    endlocal

:setbase 
    echo ::::: setting up base :::::
    chdir /D C:

    rem the base dir for app to exists=> %1
    chdir %~1 
    exit /b 0

:check 
    echo ::::: checking for local web server destination :::::
    call :setbase %~1

    set %~3= dir /p|find /C "%~2"
    exit /b 0

:create 
    echo ::::: creating the app folders :::::

    rem setting the base to create app folder %1
    call :setbase %~1
    mkdir %~2
    exit /b 0

endlocal

This is the output i get when i initiate deploy.bat

*********************************************
   Deploying in production mode: 19:28:53.13
       Deploy path: C:/wamp64/www/test
*********************************************
::::: checking for local web server destination :::::
::::: setting up base :::::
0
::::: creating the app folders :::::
::::: setting up base :::::
A subdirectory or file test already exists.

seems like the If !_flag!==0 which is checking whether the app folder exist in the server root and is not working at all. When i learnt the way to pass parameters to other functions; i thought it as passing a pointer like reference but it looks like it is deeply tied to scope. So what's going on here in the code.

like image 597
LasithaMD Avatar asked Dec 15 '25 05:12

LasithaMD


1 Answers

Checking for File/Dir Existence

The code you're employing to verify that a directory (?) exists is

set %~3= dir /p|find /C "%~2"

I don't think this is doing what you intend. SET /P is often used like this in order to pipe the output of a command into an environment variable. (Though, you are giving /P to dir, which paginates the output—probably not what you intended.) The command you have won't do that, though. I'd guess that what this is accomplishing is setting the var to (literally) " dir /p" and then piping that through find-count. That results of find.exe /C never make it back into the envvar though. The output line "0" is the result of piping (nothing) through find.exe /C.

I propose a simpler test for existence:

IF EXIST "%~2" (SET /A %~3=1) ELSE (SET /A %~3=0)

This test worked on my Win10 machine.

I have seen some variance in how IF EXIST works. If you didn't want to use that, you could do it with a FOR loop.

FOR /F "tokens=*" %%e IN ('DIR /B') DO IF "%%~e"=="%~2" SET /A %~3=1

If you want to use the pipe in the FOR command, you'll have to escape it.

FOR /F "tokens=*" %%e IN ('DIR /B ^| find /C "%~2"') DO SET /A %~3=%%~e

All three of these methods worked for me.

SETLOCAL

I do not think there exists an official reference guide for cmd syntax other than the built-in help (SETLOCAL /?)

My experience with it is that it pushes all the envvars and working directories onto a "stack" and a corresponding ENDLOCAL or EXIT (though in scripts, you almost always want to use EXIT /B) will pop the environment off that "stack." In effect, it means that envvar/CWD changes you make in a SETLOCAL will only be temporary.

like image 167
mojo Avatar answered Dec 16 '25 21:12

mojo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!