ProgramingTip

어디에 있습니까?

bestdevel 2020. 9. 27. 13:16
반응형

어디에 있습니까?


파일에 하드 코딩하지 않고 실행시 배치 파일에 ID와 암호를 전달해야합니다.

명령 줄은 다음과 달라집니다.

test.cmd admin P@55w0rd > test-log.txt

또 다른 유용한 팁은 %*"모두"를 의미하는 것입니다. 예를 들면 :

echo off
set arg1=%1
set arg2=%2
shift
shift
fake-command /u %arg1% /p %arg2% %*

때 때 :

test-command admin password foo bar

위의 배치 파일이 실행됩니다.

fake-command /u admin /p password admin password foo bar

구문이 약간의 오류 수 있습니다.


내가 한 방법은 다음과 가변적이다.

@fake-command /u %1 /p %2

명령은 다음과 달라집니다.

test.cmd admin P@55w0rd > test-log.txt

%1제 매개 변수 적용 %2(여기 까다로운 부분이다) 제에 적용된다. 대체 방식으로 최대 9 개의 매개 변수를 사용할 수 있습니다.


누락 된 매개 변수를 지능적으로 처리 할 다음과 같이 할 수 있습니다.

IF %1.==. GOTO No1
IF %2.==. GOTO No2
... do stuff...
GOTO End1

:No1
  ECHO No param 1
GOTO End1
:No2
  ECHO No param 2
GOTO End1

:End1

배치 변수에 액세스하는 것은 % 1, % 2, ... % 9 또는 % *를
사용하여 간단하게 할 수있는 내용이 단순한 경우에만 가능합니다.

"&"^&% 1에 액세스 할 수 없기 때문에 같은 복잡한 내용에 대한 간단한 방법은 없습니다 .

set  var=%1
set "var=%1"
set  var=%~1
set "var=%~1"

라인 확장

set  var="&"&
set "var="&"&"
set  var="&"&
set "var="&"&"

그리고 그 중 하나가 &따옴표 있기 때문에 각 줄이 실패 합니다.

임시 파일에서 언급 된 변수 버전을 읽어서 수 있습니다 .

@echo off
SETLOCAL DisableDelayedExpansion

SETLOCAL
for %%a in (1) do (
    set "prompt="
    echo on
    for %%b in (1) do rem * #%1#
    @echo off
) > param.txt
ENDLOCAL

for /F "delims=" %%L in (param.txt) do (
  set "param1=%%L"
)
SETLOCAL EnableDelayedExpansion
set "param1=!param1:*#=!"
set "param1=!param1:~0,-2!"
echo %%1 is '!param1!'

트릭은 echo on더 이상 % 1 을 활성화 하고 확장하는 rem것입니다 (와 함께 작동 함 %2 .. %*).
따라서 "&"&오류가 발생하지 않고 에코 될 수도 있습니다.

그러나 echo on루프가 필요하기 때문에 두 개의 리디렉션이 필요합니다.

추가 문자 * #/?(에 대한 도움말을 표시합니다) 와 같은 내용에 대해 안전을 위해 사용 REM됩니다.
또는 줄 끝의 캐럿 ^은 rem.

그런 다음 파일에서 출력되는 rem 변수를 주의 깊게 읽습니다 .
FOR / F는 지연 확장이 해제 된 상태에서 작동해야하며 "!" 파괴 될 것입니다.
에서 추가 문자를 제거한 후 가져 왔습니다 param1.

그리고 확장을 사용하여 param1안전한 방식으로, 지연을 가능하게합니다.


네, 그리고 을 사용할 %%1if같은 변수를 사용하는 것을 잊지 않습니다 for.

double을 잊어 버리면 %(null 일 수있는) 명령 줄 인수로 대체 혼란스러운 오류 메시지가 표시됩니다.


복잡하게 할 필요가 없습니다. 예를 들어, 명령 % 1 % 2 매개 변수입니다.

@echo off

xcopy %1 %2 /D /E /C /Q /H /R /K /Y /Z

echo copied %1 to %2

pause

"일시 중지"는 배치 파일이 수행 한 작업을 표시하고 ANY 키를 누를 때까지 기다립니다. Windows 폴더에 xx.bat로 저장됩니다.

이를 입력하십시오.

xx c:\f\30\*.* f:\sites\30

이 배치 파일은 최신 파일 만 복사하는 등 필요한 모든 매개 변수를 처리합니다. Windows 이전부터 사용했습니다. 복사중인 파일의 이름을보고 컨텐츠를 Q생략 하십시오 .


최근에 친구 가이 주제에 대해 물어 봤기 때문에 배치 파일에서 명령 줄 인수를 처리하는 방법을 게시 할 생각했습니다.

이 기술은 보시다시피 약간의 오버 헤드가 배치 파일을 이해하기 쉽게 구현할 수 있습니다. 다음 구조를 지원합니다.

>template.bat [-f] [--flag] [/f] [--namedvalue value] arg1 [arg2][arg3][...]

그것의 JIST가 구비되고 :init, :parse그리고 :main기능.

사용 예

>template.bat /?
test v1.23
This is a sample batch file template,
providing command-line arguments and flags.

USAGE:
test.bat [flags] "required argument" "optional argument"

/?, --help           shows this help
/v, --version        shows the version
/e, --verbose        shows detailed output
-f, --flag value     specifies a named parameter value

>template.bat          <- throws missing argument error
(same as /?, plus..)
****                                   ****
****    MISSING "REQUIRED ARGUMENT"    ****
****                                   ****

>template.bat -v
1.23

>template.bat --version
test v1.23
This is a sample batch file template,
providing command-line arguments and flags.

>template.bat -e arg1
**** DEBUG IS ON
UnNamedArgument:    "arg1"
UnNamedOptionalArg: not provided
NamedFlag:          not provided

>template.bat --flag "my flag" arg1 arg2
UnNamedArgument:    "arg1"
UnNamedOptionalArg: "arg2"
NamedFlag:          "my flag"

>template.bat --verbose "argument #1" --flag "my flag" second
**** DEBUG IS ON
UnNamedArgument:    "argument #1"
UnNamedOptionalArg: "second"
NamedFlag:          "my flag"

template.bat

@::!/dos/rocks
@echo off
goto :init

:header
    echo %__NAME% v%__VERSION%
    echo This is a sample batch file template,
    echo providing command-line arguments and flags.
    echo.
    goto :eof

:usage
    echo USAGE:
    echo   %__BAT_NAME% [flags] "required argument" "optional argument" 
    echo.
    echo.  /?, --help           shows this help
    echo.  /v, --version        shows the version
    echo.  /e, --verbose        shows detailed output
    echo.  -f, --flag value     specifies a named parameter value
    goto :eof

:version
    if "%~1"=="full" call :header & goto :eof
    echo %__VERSION%
    goto :eof

:missing_argument
    call :header
    call :usage
    echo.
    echo ****                                   ****
    echo ****    MISSING "REQUIRED ARGUMENT"    ****
    echo ****                                   ****
    echo.
    goto :eof

:init
    set "__NAME=%~n0"
    set "__VERSION=1.23"
    set "__YEAR=2017"

    set "__BAT_FILE=%~0"
    set "__BAT_PATH=%~dp0"
    set "__BAT_NAME=%~nx0"

    set "OptHelp="
    set "OptVersion="
    set "OptVerbose="

    set "UnNamedArgument="
    set "UnNamedOptionalArg="
    set "NamedFlag="

:parse
    if "%~1"=="" goto :validate

    if /i "%~1"=="/?"         call :header & call :usage "%~2" & goto :end
    if /i "%~1"=="-?"         call :header & call :usage "%~2" & goto :end
    if /i "%~1"=="--help"     call :header & call :usage "%~2" & goto :end

    if /i "%~1"=="/v"         call :version      & goto :end
    if /i "%~1"=="-v"         call :version      & goto :end
    if /i "%~1"=="--version"  call :version full & goto :end

    if /i "%~1"=="/e"         set "OptVerbose=yes"  & shift & goto :parse
    if /i "%~1"=="-e"         set "OptVerbose=yes"  & shift & goto :parse
    if /i "%~1"=="--verbose"  set "OptVerbose=yes"  & shift & goto :parse

    if /i "%~1"=="--flag"     set "NamedFlag=%~2"   & shift & shift & goto :parse

    if not defined UnNamedArgument     set "UnNamedArgument=%~1"     & shift & goto :parse
    if not defined UnNamedOptionalArg  set "UnNamedOptionalArg=%~1"  & shift & goto :parse

    shift
    goto :parse

:validate
    if not defined UnNamedArgument call :missing_argument & goto :end

:main
    if defined OptVerbose (
        echo **** DEBUG IS ON
    )

    echo UnNamedArgument:    "%UnNamedArgument%"

    if defined UnNamedOptionalArg      echo UnNamedOptionalArg: "%UnNamedOptionalArg%"
    if not defined UnNamedOptionalArg  echo UnNamedOptionalArg: not provided

    if defined NamedFlag               echo NamedFlag:          "%NamedFlag%"
    if not defined NamedFlag           echo NamedFlag:          not provided

:end
    call :cleanup
    exit /B

:cleanup
    REM The cleanup function is only really necessary if you
    REM are _not_ using SETLOCAL.
    set "__NAME="
    set "__VERSION="
    set "__YEAR="

    set "__BAT_FILE="
    set "__BAT_PATH="
    set "__BAT_NAME="

    set "OptHelp="
    set "OptVersion="
    set "OptVerbose="

    set "UnNamedArgument="
    set "UnNamedArgument2="
    set "NamedFlag="

    goto :eof

@ECHO OFF
:Loop
IF "%1"=="" GOTO Continue
SHIFT
GOTO Loop
:Continue

참고 : IF 자체가 따옴표로 묶여 있으면 "%1"==""문제가 발생 %1합니다.

이 경우 IF [%1]==[]또는 IF "%~1"==""대신 NT 4 (SP6) 이상에서만 사용하십시오.


간단하게 유지합시다.

다음은 .cmd 파일입니다.

@echo off
rem this file is named echo_3params.cmd
echo %1
echo %2
echo %3
set v1=%1
set v2=%2
set v3=%3
echo v1 equals %v1%
echo v2 equals %v2%
echo v3 equals %v3%

다음은 명령 줄에서 3 번의 호출입니다.

C:\Users\joeco>echo_3params 1abc 2 def  3 ghi
1abc
2
def
v1 equals 1abc
v2 equals 2
v3 equals def

C:\Users\joeco>echo_3params 1abc "2 def"  "3 ghi"
1abc
"2 def"
"3 ghi"
v1 equals 1abc
v2 equals "2 def"
v3 equals "3 ghi"

C:\Users\joeco>echo_3params 1abc '2 def'  "3 ghi"
1abc
'2
def'
v1 equals 1abc
v2 equals '2
v3 equals def'

C:\Users\joeco>

FOR %%A IN (%*) DO (
    REM Now your batch file handles %%A instead of %1
    REM No need to use SHIFT anymore.
    ECHO %%A
)

이렇게하면 따옴표가 있거나 배치 된 배치 변수 (% *)를 반복 한 다음 각 변수를 에코합니다.


함수 (또는 외부 .bat) 로 호출 할 수있는 간단한 read_params 펼쳐보기 작성하고 모든 변수를 현재 환경에 넣습니다. 가 함수 call원래 매개 변수의 사본 으로 편집 되고 있기 때문에 원래 매개 변수를 수정하지 않습니다 .

예를 들어, 다음 명령이 제공됩니다.

myscript.bat some -random=43 extra -greeting="hello world" fluff

myscript.bat 함수를 호출 한 후 변수를 사용할 수 있습니다.

call :read_params %*

echo %random%
echo %greeting%

기능은 다음과 가변합니다.

:read_params
if not %1/==/ (
    if not "%__var%"=="" (
        if not "%__var:~0,1%"=="-" (
            endlocal
            goto read_params
        )
        endlocal & set %__var:~1%=%~1
    ) else (
        setlocal & set __var=%~1
    )
    shift
    goto read_params
)
exit /B

한계

  • 과 같은 값이없는 인수는로드 할 수 없습니다 -force. 사용할 수 -force=true없는 값을 미리 알지 않고 빈 값을 허용하는 방법을 사용할 수 없습니다.

변경 로그

  • 2016 년 2 월 18 일
    • 더 이상 지연된 확장이 필요하지 않습니다.
    • 이제 -매개 변수 앞에 를 찾아 다른 명령 줄 인수와 함께 작동합니다 .

명령 줄에서 설정 변수를 참조 다음과 같이 설정합니다 %a%.

set a=100 
echo %a%  
rem output = 100 

참고 : 이것은 Windows 7 pro에서 작동합니다.


@Jon 다른 답변에서 영감을 받아 명명 된 변수, 앞에서 값 및 스위치를 추출하는 알고리즘을 만들었습니다.

유틸리티를 구현하고 싶다고 가정 해봅시다 foobar. 초기 명령이 필요합니다. 선택적--foo을 취하는 선택적 매개 변수 있습니다 (물론 다른 매개 변수 일 수 없음). 값이 누락 된 경우 경우는 입니다. 또한 필수 값을 사용 하는 일련의 변수 있습니다. 으로 마지막 값이 허용되지 않는 플래그 취할 수 있습니다 . 아, 그리고 우선 순위 변수는 임의의 순서로 올 수 있습니다.default--bar--baz

즉, 다음과 같이 시청합니다.

foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]

해결책은 다음과 가변합니다.

@ECHO OFF
SETLOCAL
REM FooBar parameter demo
REM By Garret Wilson

SET CMD=%~1

IF "%CMD%" == "" (
  GOTO usage
)
SET FOO=
SET DEFAULT_FOO=default
SET BAR=
SET BAZ=

SHIFT
:args
SET PARAM=%~1
SET ARG=%~2
IF "%PARAM%" == "--foo" (
  SHIFT
  IF NOT "%ARG%" == "" (
    IF NOT "%ARG:~0,2%" == "--" (
      SET FOO=%ARG%
      SHIFT
    ) ELSE (
      SET FOO=%DEFAULT_FOO%
    )
  ) ELSE (
    SET FOO=%DEFAULT_FOO%
  )
) ELSE IF "%PARAM%" == "--bar" (
  SHIFT
  IF NOT "%ARG%" == "" (
    SET BAR=%ARG%
    SHIFT
  ) ELSE (
    ECHO Missing bar value. 1>&2
    ECHO:
    GOTO usage
  )
) ELSE IF "%PARAM%" == "--baz" (
  SHIFT
  SET BAZ=true
) ELSE IF "%PARAM%" == "" (
  GOTO endargs
) ELSE (
  ECHO Unrecognized option %1. 1>&2
  ECHO:
  GOTO usage
)
GOTO args
:endargs

ECHO Command: %CMD%
IF NOT "%FOO%" == "" (
  ECHO Foo: %FOO%
)
IF NOT "%BAR%" == "" (
  ECHO Bar: %BAR%
)
IF "%BAZ%" == "true" (
  ECHO Baz
)

REM TODO do something with FOO, BAR, and/or BAZ
GOTO :eof

:usage
ECHO FooBar
ECHO Usage: foobar ^<command^> [--foo [^<fooval^>]] [--bar ^<barval^>] [--baz]
EXIT /B 1
  • SETLOCAL가 호출 Environmental & 변수으로 탈출하지 않도록 사용하십시오 .
  • SET FOO=누군가 호출 환경에서 정의한 경우 변수 을 초기화하는 것을 잊지 않고 .
  • %~1따옴표를 제거하는 데 사용 합니다.
  • 사용하지 IF "%ARG%" == ""않기 IF [%ARG%] == []때문에 [그리고 ]공간 끝나는 값으로 전혀 뜻을 재생하지 않습니다.
  • 블록 SHIFT안에 있더라도 IF와 같은 현재 인수 는 파싱 %~1될 때 결정되기 때문에 업데이트되지 않았습니다 IF. %~1그리고 블록 %~2내부에서 사용할 수 IF있습니다 SHIFT. SHIFT명확성을 위해 블록을 쌓을 있고, 그게 길을 잃거나 사람들을 혼란스럽게 할 수도 있습니다. 따라서 "캡처" %~1%~1블록 외부가 가장 좋습니다.
  • 다른 매개 변수의 우선 값 대신 선호하는 변수를 사용하고 IF NOT "%ARG:~0,2%" == "--"있습니다.
  • 매개 변수 중 하나 SHIFT사용할 때만주의하십시오 .
  • 이 코드 SET FOO=%DEFAULT_FOO%는 안타깝지만 대안은 블록 IF "%FOO%" == "" SET FOO=%DEFAULT_FOO%외부 에 추가하는 것 IF NOT "%ARG%" == ""입니다. 이것은 내부에 여전히 그러나 때문에 IF "%PARAM%" == "--foo"블록의 %FOO%값이 평가 된 경우, 당신이 이제까지 블록을 입력하기 전에 감지 절대 설정 설정 모두--foo변수가 존재 매개 하고 또한 것을 %FOO%값이 누락되었습니다.
  • 참고 ECHO Missing bar value. 1>&2stderr에 오류 메시지를 보냅니다.
  • Windows 배치 파일에 빈 줄이 필요하십니까? ECHO:또는 변형 중 하나를 사용 합니다.

새 배치 파일 (예 : openclass.bat)을 만들고 파일에 다음 줄을 작성합니다.

java %~n1

그런 다음 배치 파일을 system32 폴더에 배치하고 Java 클래스 파일로 이동 한 다음 마우스 오른쪽 버튼을 클릭하고 속성, 연결 프로그램 ...을 클릭 한 다음 배치 파일을 찾아 선택하면됩니다.

그것은 나를 위해 작동합니다.

추신 : Java 클래스를 닫을 때 cmd 창을 닫는 방법을 사용할 수 없습니다. 지금은 ...


간단한 해결책 (질문이 오래되어)

Test1.bat

echo off
echo "Batch started"
set arg1=%1
echo "arg1 is %arg1%"
echo on
pause

CallTest1.bat

call "C:\Temp\Test1.bat" pass123

많이

YourLocalPath>call "C:\Temp\test.bat" pass123

YourLocalPath>echo off
"Batch started"
"arg1 is pass123"

YourLocalPath>pause
Press any key to continue . . .

YourLocalPath는 현재 디렉토리 경로입니다.

간단하게 유지해야하는 많은 변수를 변수에 저장하고 비교를 위해 변수를 사용하십시오.

작성이 간단하게 이해하고 유지 관리도 간단하고 다른 사람이나 오랜 시간 확장을 진행합니다.

코드를 인라인으로 비용 청구 다른 답변을 참조하십시오.


여기에 이미지 설명 입력

루핑을 사용하는 모든 인수를 순수 배치로 가져옵니다.

@echo off && setlocal EnableDelayedExpansion

 set "_cnt=0" && for %%Z in (%*) do ( 
 set "_arg_=%%Z" && set /a "_cnt=!_cnt! + 1" && set "_arg_[!_cnt!]=!_arg_!"
 shift && for /l %%l in (!_cnt! 1 !_cnt!) do echo/ The argument n:%%l is: !_arg_[%%l]!
 )

goto :eof 

코드는 다음과 같이 필요한 인수 번호로 작업을 수행 할 준비가되었습니다.

 @echo off && setlocal EnableDelayedExpansion

 set "_cnt=0" && for %%Z in (%*) do ( 
 set "_arg_=%%Z" && set /a "_cnt=!_cnt! + 1" && set "_arg_[!_cnt!]=!_arg_!"
 shift 

 )

 fake-command /u !_arg_[1]! /p !_arg_[2]! > test-log.txt

참고 URL : https://stackoverflow.com/questions/26551/how-can-i-pass-arguments-to-a-batch-file

반응형