Search code examples
batch-fileechosubroutine

Echo variable out to text file within a subroutine in Batch


@echo off
Color 1A
TITLE TSM mef3 Extract Script
:start
cls
ECHO.
ECHO        ###################################
ECHO        ##        IAM TSM Extract        ##
ECHO        ##          Version 1.0          ##
ECHO        ##    Written by Kane Charles    ##
ECHO        ###################################
ECHO.
ECHO    Extraction Options:
ECHO.
REM ECHO    1. Extract all Servers
ECHO    2. Extract Server1
ECHO    3. Extract Server2
ECHO    4. Extract Server3
ECHO    4. Extract Server4
ECHO    5. Extract Server5
ECHO    6. Extract Server6
ECHO    7. Extract Server7
ECHO    0. Exit
ECHO.
ECHO    Last Option selected: %selection%
ECHO.
SET/P selection=Please enter a value: 
REM IF %selection%==1 GOTO precommands
IF %selection%==2 call:modifydsmopt 1.2.3.4,1000
IF %selection%==3 call:modifydsmopt 2.3.4.5,1001
IF %selection%==4 call:modifydsmopt 3.4.5.6,1002
IF %selection%==5 call:modifydsmopt 4.5.6.7,1003
IF %selection%==6 call:modifydsmopt 5.6.7.8,1004
IF %selection%==7 call:modifydsmopt 6.7.8.9,1005
IF %selection%==8 call:modifydsmopt 7.8.9.10,1006
IF %selection%==0 exit

pushd C:\Program Files\Tivoli\TSM\baclient

:modifydsmopt
SETLOCAL enabledelayedexpansion
SET IP=%~1
SET PORT=%~2


IF EXIST dsm.opt.bak (
    del dsm.opt.bak
)

IF EXIST dsm.opt (
    ren dsm.opt dsm.opt.bak
)

ECHO commmethod             TCPIP >> dsm.opt
ECHO PASSWORDACCESS         GENERATE >> dsm.opt
ECHO TCPSERVERADDRESS       %IP% >> dsm.opt
ECHO TCPPORT                %PORT% >> dsm.opt

ECHO IP: %IP%, PORT: %PORT%

rem GOTO EOF
ENDLOCAL


popd

:EOF

I've masked the IP addresses and ports for security reasons, obviously they're not real.

The aim of this batch file is to create a fresh dsm.opt file that looks like the following:

commmethod              TCPIP 
PASSWORDACCESS          GENERATE 
TCPSERVERADDRESS        1.2.3.4 
TCPPORT                 1000

The following two lines do not work:

ECHO TCPSERVERADDRESS       %IP% >> dsm.opt
ECHO TCPPORT                %PORT% >> dsm.opt

However the following line works fine:

ECHO IP: %IP%, PORT: %PORT%

So essentially, I can write plain text out to a file, I can echo the variables out to the console, but I can't echo the variables out to a text file.

When run, the subroutine is producing this:

commmethod              TCPIP 
PASSWORDACCESS          GENERATE 
TCPSERVERADDRESS     
TCPPORT 

Can someone please help me with outputting the variables out to a file?

Cheers.


Solution

  • As published, your batch has distinct echoes of attempts to solve problems. I'd suggest you look in dsm.opt.bak for the elusive data.

    :modifydsmopt has unbalanced setlocal and endlocal as configured, similarly, popd and pushd

    Unlike many languages, batch has no concept of sections or procedures so after CALLing :modifydsmopt, execution returns to the instruction following the call, ignores the remaining matches on selection (because selection will not match any of the remaining values) and proceed to the push; then re-enter the :modifydsmopt subroutine - this time with no parameters, possibly having changed directory (courtesy the push) and hence generates a (new?) output file.

    The cure is simple.

    ...
    IF %selection%==0 exit
    
    :: I've no idea what this change-of-directory is aimed at, so REM it out...
    REM pushd C:\Program Files\Tivoli\TSM\baclient
    
    :: We're done - so exit
    GOTO :EOF
    
    :modifydsmopt
    SETLOCAL enabledelayedexpansion
    SET IP=%~1
    SET PORT=%~2
    
    
    IF EXIST dsm.opt.bak (
        del dsm.opt.bak
    )
    
    IF EXIST dsm.opt (
        ren dsm.opt dsm.opt.bak
    )
    
    ECHO commmethod             TCPIP >> dsm.opt
    ECHO PASSWORDACCESS         GENERATE >> dsm.opt
    ECHO TCPSERVERADDRESS       %IP% >> dsm.opt
    ECHO TCPPORT                %PORT% >> dsm.opt
    
    ECHO IP: %IP%, PORT: %PORT%
    
    GOTO EOF
    

    Note: I've removed the popd - possibly you want to move to the directory first, make the changes, then popd back - which means the pushd should be done before selection is evaluated or is performed in the :modifydsmopt routine. Also the :EOF label has disappeared - it is not required - cmd assumes goto :EOF means go to end-of-file IMHO, it should not be declared. Also, the goto :eof (or reaching EOF) is an implicit endlocal.

    What also jumps out is that the setlocal and setting of variables appears redundant. Try this:

    ...
    IF %selection%==0 exit
    
    :: We're done - so exit
    GOTO :EOF
    
    :modifydsmopt
    pushd C:\Program Files\Tivoli\TSM\baclient
    
    IF EXIST dsm.opt.bak (
        del dsm.opt.bak
    )
    
    IF EXIST dsm.opt (
        ren dsm.opt dsm.opt.bak
    )
    
    ECHO commmethod             TCPIP >> dsm.opt
    ECHO PASSWORDACCESS         GENERATE >> dsm.opt
    ECHO TCPSERVERADDRESS       %~1 >> dsm.opt
    ECHO TCPPORT                %~2 >> dsm.opt
    
    ECHO IP: %~2, PORT: %~2
    
    POPD
    
    GOTO EOF
    

    which will switch to the target directory for the file-manipulation, then switch back. Also not use the variables, so no need to set a local environment.