etc./StackOverFlow

배치 파일에 인수를 전달하려면 어떻게 해야 합니까?

청렴결백한 만능 재주꾼 2023. 4. 25. 10:56
반응형

질문자 :Keng


파일에 하드코딩 하지 않고 실행시 배치파일에 아이디와 비밀번호를 전달해야 합니다.

명령줄은 다음과 같습니다.

 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

구문이 약간 틀릴 수 있지만 이것이 일반적인 생각입니다.


Greg Hewgill

내가 한 방법은 다음과 같습니다.

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

명령은 다음과 같습니다.

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

%1 은 첫 번째 매개변수에 적용되고 %2 (여기서 까다로운 부분이 있음)는 두 번째 매개변수에 적용됩니다. 이 방법으로 최대 9개의 매개변수를 전달할 수 있습니다.


Keng

누락된 매개변수를 지능적으로 처리하려면 다음과 같이 하면 됩니다.

 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

thelsdj

배치 매개변수에 액세스하는 것은 %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 rem 문 다음에 %1을 확장하는 것 %2 .. %* 에서도 작동함).
따라서 "&"& 도 표시된 대로 오류를 생성하지 않고 반향될 수 있습니다.

echo on 의 출력을 리디렉션할 수 있으려면 두 개의 for 루프가 필요합니다.

추가 문자 * #/? REM 대한 도움말을 표시합니다).
rem 뒤에도 여러 줄 문자로 작동할 수 있습니다.

그런 다음 파일에서 rem 매개변수 출력을 읽어야 합니다.
FOR /F는 지연된 확장을 끈 상태에서 작동해야 하며, 그렇지 않으면 "!" 파괴될 것이다.
param1 에서 추가 문자를 제거한 후 얻었습니다.

그리고 param1 을 안전하게 사용하려면 지연 확장을 활성화하십시오.


jeb

if , for 및 gang을 사용할 때 %%1 과 같은 변수를 사용하는 것을 잊지 마십시오.

% 를 잊어버린 경우 (null 가능성이 있는) 명령줄 인수를 대체하게 되며 꽤 혼란스러운 오류 메시지를 받게 됩니다.


Frank Krueger

그것을 복잡하게 할 필요가 없습니다. 단순히 명령 %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 매개변수를 생략하십시오.


DearWebby

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

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

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

그것의 요지는 :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"

템플릿.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

kodybrown

배치 파일에서

 set argument1=%1 set argument2=%2 echo %argument1% echo %argument2%

%1%2 는 각각 첫 번째 및 두 번째 인수 값을 반환합니다.

그리고 명령줄에서 인수를 전달합니다.

 Directory> batchFileName admin P@55w0rd

출력은

 admin P@55w0rd

The Godfather

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

참고: IF "%1"=="" %1 이(가) 따옴표로 묶인 경우 문제를 일으킵니다.

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


rightcodeatrighttime

이것을 간단하게 유지합시다.

다음은 .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>

Love and peace - Joe Codeswell

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

이것은 배치 매개변수(%*)를 따옴표로 묶었는지 여부에 관계없이 반복한 다음 각 매개변수를 에코합니다.


Amr Ali

.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일
    • 더 이상 지연된 확장이 필요하지 않습니다.
    • 이제 매개변수 앞에 - 를 찾아 다른 명령줄 인수와 함께 작동합니다.

Evan Kennedy

@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 사용하십시오.
  • 호출 환경에서 누군가 정의한 경우 SET FOO= 등을 초기화하는 것을 잊지 마십시오.
  • 따옴표를 제거 %~1 을 사용하십시오.
  • IF [%ARG%] == [] ] IF "%ARG%" == "" 사용하십시오. [ 및 ]는 공백으로 끝나는 값으로 전혀 재생되지 않기 때문입니다.
  • IF 블록 내에서 SHIFT 하더라도 %~1 과 같은 현재 인수 IF 가 구문 분석될 때 결정되기 때문에 업데이트되지 않습니다. IF 블록 내에서 %~1%~2 사용할 수 SHIFT 가 있기 때문에 혼란스러울 수 있습니다. SHIFT 를 둘 수 있지만, 이는 사람들을 잃어버리거나 혼동을 줄 수도 있습니다. %~1%~1 "캡처"하는 것이 가장 좋습니다.
  • 다른 매개변수의 선택적 값 대신 매개변수를 사용하고 싶지 않으므로 IF NOT "%ARG:~0,2%" == "--" 합니다.
  • 매개변수 중 하나를 사용할 SHIFT 주의하십시오.
  • 중복 코드 SET FOO=%DEFAULT_FOO% IF NOT "%ARG%" == "" 블록 외부에 IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% 를 추가하는 것입니다. . 그러나 이것은 여전히 IF "%PARAM%" == "--foo" 블록 %FOO% 값은 블록에 들어가기 전에 평가되고 설정되었을 것이므로 두 가지 모두 --foo 파라미터가 존재하고, 또한이었다 %FOO% 값이 누락되었다.
  • ECHO Missing bar value. 1>&2 유의하십시오. ECHO Missing bar value. 1>&2 는 오류 메시지를 stderr에 보냅니다.
  • Windows 배치 파일에 빈 줄을 원하십니까? ECHO: 또는 변형 중 하나를 사용해야 합니다.

Garret Wilson

명령줄에서 set 변수를 참조하려면 %a% 를 사용해야 합니다. 예를 들면 다음과 같습니다.

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

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


CMS_95

여기에 이미지 설명 입력

루핑을 사용하려면 모든 인수를 순수 일괄 처리로 가져옵니다.

Obs: 없이 사용: ?*&|<>


 @echo off && setlocal EnableDelayedExpansion for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && ( call set "_arg_[!_cnt!]=!_arg_!" && for /l %%l in (!_cnt! 1 !_cnt! )do echo/ The argument n:%%l is: !_arg_[%%l]! ) goto :eof

귀하의 코드는 다음과 같이 필요한 경우 인수 번호로 무언가를 할 준비가 되었습니다.

 @echo off && setlocal EnableDelayedExpansion for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && call set "_arg_[!_cnt!]=!_arg_!" fake-command /u !_arg_[1]! /p !_arg_[2]! > test-log.txt

It Wasn't Me

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

 java %~n1

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

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

추신: Java 클래스를 닫을 때 cmd 창을 닫는 방법을 찾을 수 없습니다. 당분간...


SvenVP

모두가 정말 복잡한 답변으로 대답했지만 실제로는 정말 간단합니다. %1 %2 %3 등은 파일로 구문 분석된 인수입니다. %1 은 인수 1, %2 는 인수 2 등입니다.

따라서 다음을 포함하는 박쥐 스크립트가 있는 경우:

 @echo off echo %1

배치 스크립트를 실행할 때 다음을 입력합니다.

 C:> script.bat Hello

스크립트는 단순히 다음을 출력합니다.

 Hello

이것은 이름 및 나이와 같은 스크립트의 특정 변수에 매우 유용할 수 있습니다. 따라서 다음과 같은 스크립트가 있는 경우:

 @echo off echo Your name is: %1 echo Your age is: %2

내가 이것을 입력할 때:

 C:> script.bat Oliver 1000

나는 이것의 출력을 얻는다 :

 Your name is: Oliver Your age is: 1000

i Mr Oli i

간단한 솔루션(질문이 오래된 경우에도)

테스트1.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는 현재 디렉토리 경로입니다.

일을 단순하게 유지하려면 명령 매개변수를 변수에 저장하고 비교를 위해 변수를 사용하십시오.

작성이 간단할 뿐만 아니라 유지 관리도 간단하므로 나중에 다른 사람이나 당신이 오랜 시간 후에 스크립트를 읽으면 이해하고 유지 관리하기 쉽습니다.

코드를 인라인으로 작성하려면 다른 답변을 참조하세요.


Amol Patil

쌍을 이루는 인수

키-값 쌍으로 인수를 전달하는 것을 선호하는 경우 다음과 같이 사용할 수 있습니다.

 @echo off setlocal enableDelayedExpansion ::::: asigning arguments as a key-value pairs::::::::::::: set counter=0 for %%# in (%*) do ( set /a counter=counter+1 set /a even=counter%%2 if !even! == 0 ( echo setting !prev! to %%# set "!prev!=%%~#" ) set "prev=%%~#" ) :::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: showing the assignments echo %one% %two% %three% %four% %five% endlocal

그리고 예:

 c:>argumentsDemo.bat one 1 "two" 2 three 3 four 4 "five" 5 1 2 3 4 5

미리 정의된 변수

일부 환경 변수를 미리 설정할 수도 있습니다. 콘솔에서 설정하거나 내 컴퓨터에서 설정하여 수행할 수 있습니다.

 @echo off if defined variable1 ( echo %variable1% ) if defined variable2 ( echo %variable2% )

다음과 같이 호출합니다.

 c:\>set variable1=1 c:\>set variable2=2 c:\>argumentsTest.bat 1 2

나열된 값이 있는 파일

필요한 값이 미리 설정된 파일을 가리킬 수도 있습니다. 이것이 스크립트인 경우:

 @echo off setlocal :::::::::: set "VALUES_FILE=E:\scripts\values.txt" ::::::::::: for /f "usebackq eol=: tokens=* delims=" %%# in ("%VALUES_FILE%") do set "%%#" echo %key1% %key2% %some_other_key% endlocal

및 값 파일은 다음과 같습니다.

 :::: use EOL=: in the FOR loop to use it as a comment key1=value1 key2=value2 :::: do not left spaces arround the = :::: or at the begining of the line some_other_key=something else and_one_more=more

호출 출력은 다음과 같습니다.

값1 값2 다른 것

물론 모든 접근 방식을 결합할 수 있습니다. 인수 구문 도 확인하고 시프트


npocmaka

보안/암호 도용이 걱정된다면(데이터베이스 없이 정적 하드 코딩 대신 실행 시 로그인 자격 증명을 사용하는 이 솔루션을 설계하게 됨) 암호화된 암호를 파일 프로그램 코드에 저장할 수 있습니다. 따라서 런타임에 사용자는 실행을 위해 프로그램 코드에 전달되기 전에 해시/암호화할 콘솔에 사용자 이름/비밀번호를 입력합니다.

다른 로그인의 출력/효과를 보기 위해 테스트 파일을 만드는 경우 명령줄에 앉아서 모두 입력하지 않는 한 모든 로그인을 암호화된 파일에 저장하여 test.cmd에 인수로 전달할 수 있습니다. 완료될 때까지 로그인합니다.

제공할 수 있는 인수의 수는 명령줄의 총 문자 수로 제한됩니다. 이 제한을 극복하기 위해 이전 단락 트릭은 사용자 암호 노출 위험 없이 해결 방법입니다.


Zimba

출처 : http:www.stackoverflow.com/questions/26551/how-can-i-pass-arguments-to-a-batch-file

반응형