【问题标题】:Batch - Passing variable from subroutine to subroutine error批处理 - 将变量从子程序传递到子程序错误
【发布时间】:2015-08-04 16:05:52
【问题描述】:

Main_Control 是父批次。 它调用名为 DEFAULT、SETOPTIONS 和 USEROPTIONS 的批次。 DEFAULT 将变量 %def_set% 设置为 1 或 2。 %def_set% 在 USEROPITONS 中用于设置在 SETOPITONS 中使用的一些其他变量。在 DEFAULT 之后,在 MAIN_CONTROL 中,对 %def_set% 的测试返回错误“'1'(或 '2')对于 %def_set%=1 或 2 都不是内部或外部命令、程序或批处理”。它似乎没有正确传递变量。我做错了什么?

------------代码---------- ---

“Main_Control”=批次1

@ECHO off 
CLS
MODE CON:cols=130 lines=75


REM This particular file is the control script which CALLs the subroutines to perform the back or restore of settings. 
:skipintro

REM 1. Get backup location and subroutine location/names.
REM 2. Clear screen
REM 3. Display the notes text file in the window (must be paused).
REM 4. Pause to read notes
REM 4. Get user name
REM 6. "START1" label.  Start point if the user wants to rerun backup/restore in same session.
REM 7. Ask if user wants to backup or restore
REM 8. Ask what settings to backup/restore
REM 9. Ask if the user wants to use default settings
REM 10. If user wants to change default settings, provide options to change.
REM 11. Set the options to use throughout the backup/restore.

CALL "%~DP0"_BackupLocation_Subroutines.bat
CLS
TYPE %NOTES%
Timeout /t 30
CALL %GETUSERNAME%

:START1
CALL %B_R_OPTION%
CALL %MENU%
CALL %DEFAULTS%
rem test1
echo before & %def_set% & pause
rem END TEST1
CALL %USEROPTIONS%
REM TEST2
echo  after & %def_set% & pause
REM END TEST2   
CALL %SETOPTIONS%

Echo You are back in %~n0.
Echo You chose action: %ACTION%
Echo You chose to %ACTION%: %SELECTION%
Timeout /T 5

:: Create (for backups) or verify existence (for restores) the Main Backup and Registry Folders.
SETLOCAL ENABLEDELAYEDEXPANSION

SET FOLDERS= ^
%BACKUP_FOLDER% ^
%REGISTRY_FOLDER%

IF %ACTION%==Backup CALL %CREATE%
IF %ACTION%==Restore CALL %VERIFY%

ETC ETC ETC

%DEF_set% 必须从 DEFAULTS 传递到 USEROPTIONS 和 SETOPTIONS。但事实并非如此。

默认批次

@echo off

REM  Name:  DEFAULTS

REM  Asks user to use defaults and have no more prompts or to be prompted for inputs.

:def_input
CLS
ECHO Would you like to use default values?
ECHO    Backup location:  %Backup_Folder%   (cannot modify at this time)
ECHO    Overwrite previous backup:      No
ECHO    Rename previous backup with date/time:  Yes
ECHO    Prompt to overwrite files:      No  (no option to change)
ECHO    Prompt to delete files:         No
ECHO    Generate a log:             Yes
ECHO    Overwrite or append to an existing log: Overwrite
ECHO    Log file located in backup location:    Yes (no option to change)   
ECHO.
ECHO  1. Yes
ECHO  2. No
ECHO.
Set /P Def_SET= Choose:  
ECHO.
FOR %%w in (1 2) DO IF #%Def_SET%==#%%w (
    ECHO You selected: %Def_SET%
    Timeout /T 5
    Exit /b
    )


REM USER ERROR
REM If the user types something other than 1 or 2, the FOR/DO/IF statement won't run indicating user error. 
REM The routine will continue here, letting the user know there is an error.
ECHO Error
ECHO Select 1 or 2 & GOTO :def_input

此后,Main_control 批处理中的 TEST1 返回此错误“'1' 未被识别为内部或外部命令、程序或批处理”。

USEROPTIONS 批处理

@echo off
REM  Name:  USEROPTIONS
ECHO %~no & %def_set% & pause
IF %def_set%==1 GOTO :defopts
IF %def_set%==2 GOTO :askopts

:defopts

:: Overwrite previous backup
SET OW_BU=1

:: Generate a log
SET ONLog=1

:: Overwrite the log
SET OWLog=1

:: Prompt to delete files
SET Del_P=1

GOTO :EOF

:askopts
::              Questions to Users
::           Overwrite Backup Question
:: Rename the previous backup if user does not want it overwritten.
:OW_Backup
IF NOT EXIST %BACKUP_FOLDER%\ GOTO :skipOWQ
REM If previous backup does not exist, skip question to overwrite it.

ECHO.
ECHO Do you want to OVERWRITE the previous backup.  Choose:
ECHO  1. Do not overwrite old backup,then rename it with its "created" date.
ECHO  2. Overwrite old backup.
ECHO.   
SET /P OW_BU= Make a selection...
FOR %%u in (1 2) DO IF #%OW_BU%==#%%u (
    ECHO You selected: %OW_BU%
    GOTO SkipError1
    )
REM Error
ECHO.
ECHO.
ECHO *********Error*************
ECHO Select 1 or 2 & GOTO :OW_Backup
:SkipError1
:skipOWQ        

::              Generate Robocopy Log

:GenLog
ECHO.
ECHO Do you want to GENERATE a Robocopy log?
ECHO It will be located in %Backup_Folder%.
ECHO  1. Yes
ECHO  2. No
ECHO.   
SET /P ONLog= Make a selection...
FOR %%v in (1 2) DO IF #%ONLog%==#%%v (
    ECHO You selected: %ONLog%
    GOTO SkipError2
    )
REM Error
ECHO.
ECHO.
ECHO *********Error*************
ECHO Select 1 or 2 & GOTO :GenLog
:SkipError2

::          Overwrite or Append Robocopy Log
IF %ONLog%==2 GOTO :Del_Prompt
:OW_RLog
ECHO.
 ECHO Do you want to OVERWRITE the Robocopy log?
ECHO. 
ECHO  1. Yes - Overwrite
ECHO  2. No - Append to Log
ECHO.   
SET /P ONLog= Make a selection...
FOR %%v in (1 2) DO IF #%ONLog%==#%%v (
    ECHO You selected: %ONLog%
    GOTO SkipError3
    )
 REM Error
ECHO.
ECHO.
ECHO *********Error*************
ECHO Select 1 or 2 & GOTO :OW_Rlog
:SkipError3

::          Prompt to Delete Decision
:Del_Prompt
ECHO.
 ECHO.
 ECHO The restoration will delete default files that are not in your backup in order to restore your VDI to the way you had it.
ECHO Do you want confirmations to delete files?
 ECHO  1.  No confirmations to delete files.
ECHO  2.  Review and confirm to delete files.
ECHO.
 SET /P Del_P= Make a selection...
ECHO.
FOR %%x in (1 2) DO IF #%Del_P%==#%%x (
    ECHO You selected: %Del_P%
    GOTO SkipError4
    )
REM Error
ECHO.
ECHO.
ECHO *********Error*************
ECHO Select 1 or 2 & GOTO :Del_Prompt
:SkipError4

Exit /b

返回 Main_Control 批处理,然后调用 SETOPTIONS SETOPTIONS批次

@echo off

REM  Name:  SETOPTIONS

ECHO Currenlty running: %~nx0
pause

::              Set Options


ECHO Backup location is: %Backup_Folder%
REM Test
echo OnLog %Onlog%
echo Overwrite %Overwrite%
echo Del_P %del_P%
pause 


:://///////////////////////   Robocopy options    /////////////////////////////
IF %ONLog%==1 (
   IF %OWLog%==1 SET LOG=/LOG:%BACKUP_FOLDER%\Robocopy_Log.txt
    IF %OWLog%==2 SET LOG=/LOG+:%BACKUP_FOLDER%\Robocopy_Log.txt 
    ) else (
        SET LOG=
        )
SET R_OPT=/Z /MIR %LOG%
REM Removed /copyall


:://///////////////////  Overwrite Backup Code  ////////////////////////////////
 IF NOT EXIST %BACKUP_FOLDER%\ GOTO :skipOWC

IF %Overwrite%== 1 (
    ECHO.
    ECHO %BACKUP_FOLDER% will be RENAMED.
    TIMEOUT /T 2
    Call %RENAME% 
    )

IF %Overwrite%== 2 (
    Echo %BACKUP_FOLDER% will be OVERWRITTEN. 
    ECHO Close this window if you've changed your mind.
    TIMEOUT /T 10 
    )   

REM Nothing to do to overwrite old backup.  It will do it on its own with /MIR option.
:skipOWC

:://///////////////////  Prompt to Delete Code   ////////////////////////////////
IF %Del_P%== 1 SET Del_Opt_Prompt=/Q
IF %Del_P%== 2 SET DEL_Opt_Prompt=/P
DEL_OPT=/F /S %Del_Opt_Prompt%

REM Test
echo OnLog %Onlog%
echo Overwrite %Overwrite%
echo Del_P %del_P%
pause 

EXIT /b

然后返回 Main_Control 批处理。

【问题讨论】:

    标签: variables batch-file call subroutine


    【解决方案1】:

    如此多的错误和错别字。 在试图弄清楚为什么调用的批次不起作用时,我在尝试测试它时添加了更多错误。 Main_Control 中的测试包含 & 符号。

    echo before & %def_set% & pause
    

    USEROPTIONS 因拼写错误而崩溃 - 字母“o”而不是零“0”:

    ECHO %~no & %def_set% & pause
    

    SETOPTIONS 崩溃了,因为我忘记了我使用的变量。 %overwrite% 没有描述任何内容,也不存在于该行中:

    echo Overwrite %Overwrite%
    

    应该是:

    echo Overwrite backup OW_BU = %OW_BU%
    echo Overwrite log OWlog = %OWlog%
    

    SET 从行首被省略:

    DEL_OPT=/F /S %Del_Opt_Prompt%
    

    我认为这解决了我所有的问题。整天盯着这个,真是浪费昨天。简而言之,调用有效并且变量正在从子程序传递到子程序。这些错误最初都是拼写错误,当我在测试和捕获错误的尝试中引入更多拼写错误时,情况变得更糟。我厌倦了这个项目。

    【讨论】:

      【解决方案2】:

      使用^ 插入符号转义& 和号字符(将显示),如下所示:

      echo before ^& %def_set% & pause
      rem END TEST1
      CALL %USEROPTIONS%
      REM TEST2
      echo  after ^& %def_set% & pause
      

      在 Window CLI 和/或批处理中,& 和号是 one of a few with special meaning

      另请阅读Syntax : Escape Characters, Delimiters and Quotes

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-12
        • 2021-08-09
        • 1970-01-01
        • 2017-05-28
        • 1970-01-01
        • 1970-01-01
        • 2021-04-03
        • 1970-01-01
        相关资源
        最近更新 更多