Ho bisogno di passare un ID e una password a un file batch al momento dell'esecuzione piuttosto che codificarli nel file.
Ecco come appare la riga di comando:
test.cmd admin P@55w0rd > test-log.txt
Ho bisogno di passare un ID e una password a un file batch al momento dell'esecuzione piuttosto che codificarli nel file.
Ecco come appare la riga di comando:
test.cmd admin P@55w0rd > test-log.txt
Risposte:
Un altro suggerimento utile è usare %*
per significare "tutto". Per esempio:
echo off
set arg1=%1
set arg2=%2
shift
shift
fake-command /u %arg1% /p %arg2% %*
Quando corri:
test-command admin password foo bar
verrà eseguito il file batch sopra riportato:
fake-command /u admin /p password admin password foo bar
La sintassi potrebbe essere leggermente sbagliata, ma questa è l'idea generale.
shift
"schiocchi" l'argomento dalla lista. L'assunto di OP era che %*
avrebbe prodotto solo gli argomenti rimanenti, ma non funziona in questo modo, come ha detto @Joey.
fake-command /u admin /p password admin password foo bar
. Questo è stato sottolineato da @Joey molti anni fa.
Ecco come l'ho fatto:
@fake-command /u %1 /p %2
Ecco come appare il comando:
test.cmd admin P@55w0rd > test-log.txt
Il si %1
applica al primo parametro il %2
(ed ecco la parte difficile) si applica al secondo. In questo modo è possibile trasmettere fino a 9 parametri.
echo %1 %2
ed è stata respinta dal caso più semplice non tagliabile e incollabile con a @
e a fake-command
con params, pensando che avremmo avuto fake-command.bat
i contenuti più tardi (nel qual caso, il troppo complicato fake-command.bat
potrebbe dover echo %2 %4
ignorare i nomi dei parametri). Sbagliato, doofus. TL; DR: Non essere stupido come me. 1. echo echo %1 %2 > test.bat
2 test word1 word2
.. 3. Profitto.
Se vuoi gestire in modo intelligente i parametri mancanti, puoi fare qualcosa del tipo:
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
L'accesso ai parametri batch può essere semplice con% 1,% 2, ...% 9 o anche% *,
ma solo se il contenuto è semplice.
Non esiste un modo semplice per contenuti complessi come "&"^&
, in quanto non è possibile accedere a% 1 senza generare un errore.
set var=%1
set "var=%1"
set var=%~1
set "var=%~1"
Le linee si espandono a
set var="&"&
set "var="&"&"
set var="&"&
set "var="&"&"
E ogni riga ha esito negativo, poiché una delle &
è al di fuori delle virgolette.
Può essere risolto leggendo da un file temporaneo una versione commentata del parametro.
@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!'
Il trucco è abilitare echo on
ed espandere% 1 dopo rem
un'istruzione (funziona anche con %2 .. %*
).
Quindi "&"&
potrebbe anche essere ripetuto senza produrre un errore, come è stato osservato.
Ma per essere in grado di reindirizzare l'output di echo on
, sono necessari i due for-loop.
I caratteri extra * #
sono usati per essere sicuri contro contenuti come /?
(mostrerebbe l'aiuto per REM
).
Oppure un cursore ^ alla fine della riga potrebbe funzionare come un personaggio multilinea, anche dopo a rem
.
Quindi leggere l' output del parametro rem dal file, ma con attenzione.
Il FOR / F dovrebbe funzionare con l'espansione ritardata disattivata, altrimenti i contenuti con "!" sarebbe distrutto.
Dopo aver rimosso i personaggi extra param1
, ce l'hai.
E per utilizzare param1
in modo sicuro, abilitare l'espansione ritardata.
&
, la tua soluzione funziona solo con contenuti semplici
test.bat ^&
e non funziona. test.bat "&"
Funziona solo , ma non era quello il mio punto. Non puoi usare %*
, %1
in modo sicuro senza la tecnica REM
&
e commerciali e anche virgolette"
Sì, e basta non dimenticare di usare variabili come %%1
quando si utilizza if
ed for
e la banda.
Se dimentichi il doppio %
, sostituirai gli argomenti della riga di comando (possibilmente null) e riceverai alcuni messaggi di errore piuttosto confusi.
if
e for
?
for %%d in (*) do echo %%d
dalla riga di comando:for %d in (*) do echo %d
@for %%2 in (testing) do @echo %%2 %1
in un file batch, produce testing 1
quando viene chiamato con 1 ( test 1
).
%%1
non accede a un argomento della riga di comando ed è anche errato per il IF
comando. Solo il FOR
comando (nei file batch) richiede doppie percentuali, ma anche in questo %%1
caso definirebbe un parametro FOR e non accederà agli argomenti
Non è necessario complicarlo. È semplicemente il comando% 1% 2 parametri, ad esempio,
@echo off
xcopy %1 %2 /D /E /C /Q /H /R /K /Y /Z
echo copied %1 to %2
pause
La "pausa" mostra cosa ha fatto il file batch e attende che tu prema il tasto QUALSIASI. Salvalo come xx.bat nella cartella Windows.
Per usarlo, digita, ad esempio:
xx c:\f\30\*.* f:\sites\30
Questo file batch si occupa di tutti i parametri necessari, come la copia solo dei file, che sono più recenti, ecc. L'ho usato da prima di Windows. Se ti piace vedere i nomi dei file, mentre vengono copiati, lascia fuori il Q
parametro.
Un amico mi ha chiesto di questo argomento di recente, quindi ho pensato di pubblicare come gestisco gli argomenti della riga di comando in file batch.
Questa tecnica ha un po 'di sovraccarico come vedrai, ma rende i miei file batch molto facili da capire e veloci da implementare. Oltre a supportare le seguenti strutture:
>template.bat [-f] [--flag] [/f] [--namedvalue value] arg1 [arg2][arg3][...]
La jist sta avendo i :init
, :parse
e :main
funzioni.
Esempio di utilizzo
>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
Nota: IF "%1"==""
causerà problemi se %1
è racchiuso tra virgolette.
In tal caso, utilizzare invece IF [%1]==[]
o, solo in NT 4 (SP6) e versioni successive IF "%~1"==""
.
Manteniamolo semplice.
Ecco il file .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%
Qui ci sono 3 chiamate dalla riga di comando.
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
)
Questo passa sopra i parametri batch (% *) o sono quotati o meno, quindi echo ogni parametro.
test.bat *.txt
, test.bat cat^&dog
oTest.bat /?
Ho scritto un semplice script read_params che può essere chiamato come una funzione (o esterna .bat
) e inserirà tutte le variabili nell'ambiente attuale. Non modificherà i parametri originali perché la funzione viene modificata call
con una copia dei parametri originali.
Ad esempio, dato il seguente comando:
myscript.bat some -random=43 extra -greeting="hello world" fluff
myscript.bat
sarebbe in grado di usare le variabili dopo aver chiamato la funzione:
call :read_params %*
echo %random%
echo %greeting%
Ecco la funzione:
: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
limitazioni
-force
. Potresti usare -force=true
ma non riesco a pensare a un modo per consentire valori vuoti senza conoscere in anticipo un elenco di parametri che non avranno un valore.changelog
-
parametri precedenti.Nel file batch
set argument1=%1
set argument2=%2
echo %argument1%
echo %argument2%
% 1 e% 2 restituiscono rispettivamente il primo e il secondo argomento.
E nella riga di comando, passa l'arguemt
Directory> batchFileName admin P@55w0rd
L'output sarà
admin
P@55w0rd
Ispirato da una risposta altrove di @Jon, ho creato un algoritmo più generale per l'estrazione di parametri denominati, valori opzionali e switch.
Diciamo che vogliamo implementare un'utilità foobar
. Richiede un comando iniziale. Ha un parametro opzionale --foo
che accetta un valore opzionale (che ovviamente non può essere un altro parametro); se il valore non è presente, viene impostato per impostazione predefinita default
. Ha anche un parametro opzionale --bar
che accetta un valore richiesto . Infine, può prendere una bandiera --baz
senza valore consentito. Oh, e questi parametri possono arrivare in qualsiasi ordine.
In altre parole, si presenta così:
foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]
Ecco una soluzione:
@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
modo che le variabili non sfuggano all'ambiente chiamante.SET FOO=
, ecc. Nel caso in cui qualcuno le abbia definite nell'ambiente chiamante.%~1
per rimuovere le virgolette.IF "%ARG%" == ""
e non IF [%ARG%] == []
perché [
e ]
non giocare lo farà affatto con valori che finiscono in uno spazio.SHIFT
all'interno di un IF
blocco, gli argomenti attuali come %~1
non vengono aggiornati perché sono determinati quando IF
viene analizzato. Potresti usare %~1
e %~2
all'interno del IF
blocco, ma sarebbe confuso perché avevi un SHIFT
. Si potrebbe mettere la SHIFT
fine del blocco per chiarezza, ma ciò potrebbe perdersi e / o confondere anche le persone. Quindi "catturare" %~1
e %~1
fuori dal blocco sembra il migliore.IF NOT "%ARG:~0,2%" == "--"
.SHIFT
quando si utilizza uno dei parametri.SET FOO=%DEFAULT_FOO%
è deplorevole, ma l'alternativa sarebbe quella di aggiungerne uno IF "%FOO%" == "" SET FOO=%DEFAULT_FOO%
esterno al IF NOT "%ARG%" == ""
blocco. Tuttavia, poiché è ancora all'interno del IF "%PARAM%" == "--foo"
blocco, il %FOO%
valore sarebbe stato valutato e impostato prima di immettere il blocco, quindi non si rileverà mai che sia il --foo
parametro presente sia che il %FOO%
valore mancasse.ECHO Missing bar value. 1>&2
invia il messaggio di errore a stderr.ECHO:
o una delle varianti.Crea un nuovo file batch (esempio: openclass.bat) e scrivi questa riga nel file:
java %~n1
Quindi posiziona il file batch, diciamo, nella cartella system32, vai al tuo file di classe Java, fai clic con il pulsante destro del mouse, Proprietà, Apri con ..., quindi trova il tuo file batch, selezionalo e basta ...
Per me funziona.
PS: Non riesco a trovare un modo per chiudere la finestra cmd quando chiudo la classe Java. Per adesso...
start /wait java %~n1
Soluzione semplice (anche se la domanda è vecchia)
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
produzione
YourLocalPath>call "C:\Temp\test.bat" pass123
YourLocalPath>echo off
"Batch started"
"arg1 is pass123"
YourLocalPath>pause
Press any key to continue . . .
Dove YourLocalPath è il percorso della directory corrente.
Per semplificare le cose, memorizzare il comando param in variabile e utilizzare la variabile per il confronto.
Non è solo semplice da scrivere, ma è anche semplice da mantenere, quindi se dopo qualche altra persona o leggi la tua sceneggiatura dopo un lungo periodo di tempo, sarà facile da capire e mantenere.
Per scrivere il codice in linea: vedi altre risposte.
Per usare il looping ottenere tutti gli argomenti e in batch puro:
Obs: Per l'utilizzo senza:?*&<>
@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
Il tuo codice è pronto a fare qualcosa con il numero dell'argomento di cui ha bisogno, come ...
@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
?*&<>