Пакетный файл для создания подпапок - параметризованная функция - PullRequest
0 голосов
/ 07 мая 2020

Я пытаюсь создать основные каталоги с помощью функции make_dir из file1.bat и подпапок внутри основных папок из того же файла.

file1.bat Содержимое:

:make_dir
@IF NOT EXIST "Web_Files" (mkdir Web_Files)
ECHO Web_Files Directory Created

@IF NOT EXIST "C++ Files"   (mkdir C++ Files)
ECHO C++ Files Directory Created

EXIT /B 0

:make_sub_dir
@IF NOT EXIST "Web_Files"   (mkdir Web_Files)
ECHO Web_Files Directory Created

ECHO Creating %~2 Directory
@IF NOT EXIST "Web_Files\%~2" (mkdir Web_Files\%~2)
ECHO %~2 Directory Created

EXIT /B 0

From file2.bat Я вызываю эту функцию как:

SET "HTMLSubFolder=HTML"
SET "CSSSubFolder=CSS"
SET "JSSubFolder=JS"

call file1.bat make_dir
call file1.bat make_sub_dir %HTMLSubFolder%
call file1.bat make_sub_dir %CSSSubFolder%
call file1.bat make_sub_dir %JSSubFolder%

From file2.bat вызов функции, создаются только основные папки, но подпапки не создаются.

1 Ответ

1 голос
/ 07 мая 2020

Команда call может вызвать другой пакетный файл или метку в текущем, но вы пытаетесь указать оба, второй из которых просто передается в качестве аргумента первому элементу, пакетному файлу.

Однако вы можете позволить вызываемому сценарию использовать именно этот аргумент в качестве метки перехода:

  • file1.bat (вызываемый сценарий; мы может также назвать его вызываемым):

    rem /* This takes the first argument as a jump label and continues execution there;
    rem    if it fails due to an non-existent or invalid label the script terminates: */
    goto :%~1 || exit /B 1
    
    :make_dir
    rem /* Here I removed `if exist` since `mkdir` cannot create an already existing
    rem    directory anyway; to suppress the error message I appended `2> nul`: */
    mkdir "Web_Files" 2> nul
    echo  "Web_Files" directory created
    
    mkdir "C++ Files" 2> nul
    echo "C++ Files" directory created
    
    exit /B 0
    
    :make_sub_dir
    rem /* Here I remove creation of "Web_Files" as the next command would create it
    rem    anyway when it does not yet exist (if command extensions are enabled): */
    echo Creating "%~2" directory
    mkdir "Web_Files\%~2" 2> nul
    echo "%~2" directory created
    
    exit /B 0
    
  • file2.bat (вызывающий; почти не изменился, за исключением цитаты):

    SET "HTMLSubFolder=HTML"
    SET "CSSSubFolder=CSS"
    SET "JSSubFolder=JS"
    
    rem // Here I quoted the second argument to protect spaces and poisonous characters:
    call file1.bat make_dir
    call file1.bat make_sub_dir "%HTMLSubFolder%"
    call file1.bat make_sub_dir "%CSSSubFolder%"
    call file1.bat make_sub_dir "%JSSubFolder%"
    

Если бы мне пришлось реализовать такой подход, я бы все же изменил несколько вещей:

  • пусть вызываемый объект интерпретирует первый аргумент как метку только тогда, когда он начинается с :, поэтому он также может получать другие аргументы для некоторых дополнительных функций;
  • перед переходом к этой метке сдвиньте оставшиеся аргументы, чтобы больше не было разницы в ссылках на аргументы в вызываемых подпрограммах по сравнению чтобы позвонить им стажерам ally;

Вот что я имею в виду под этим (применительно к вызываемому, file1.bat):

rem /* This takes the first argument as a jump label and continues execution there;
rem    if it fails due to an non-existent or invalid label the script terminates: */

rem // Store the first argument to a variable:
set "ARG1=%~1"
rem /* Check the first character of the first argument:
rem     * if it is a colon, the argument is interpreted as a jump label;
rem       so shift all further argument references back by one, so called routines
rem       do not have to take care of the first argument (the label) anymore, which
rem       is irrelevant there anyway; then try to jump and terminate upon an error;
rem    * if it is any other character or even blank (when no argument was given),
rem      any other activity can be triggered; for example, printing a message: */
if defined ARG1 if "%ARG1:~,1%"==":" shift /1 & goto %~1 || exit /B 1
rem /* This point is reached when the first argument does not begin with `:`;
rem    you can do some default actions here, or whatever else you like. */
exit /B 0


:make_dir
::(skipping the functional code here...)
exit /B 0


:make_sub_dir
rem // Here the first argument is referred to now:
echo Creating "%~1" directory
mkdir "Web_Files\%~1" 2> nul
echo "%~1" directory created

exit /B 0
...