Domanda

Devo passare un ID e una password a un file batch al momento dell'esecuzione anziché codificarli nel file.

Ecco come appare la riga di comando:

test.cmd admin P@55w0rd > test-log.txt
È stato utile?

Soluzione 2

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 %1 si applica al primo parametro il %2 (e qui sta la parte difficile) si applica al secondo.In questo modo è possibile passare fino a 9 parametri.

Altri suggerimenti

Un altro consiglio utile è usare %* significare "tutti".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:

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

Potrei avere la sintassi leggermente sbagliata, ma questa è l'idea generale.

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 "&"^&, poiché non è possibile accedere a %1 senza produrre un errore.

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

Le linee si espandono in

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

E ogni riga fallisce, come una delle & è fuori dalle virgolette.

Può essere risolto leggendo da un file temporaneo a ha osservato versione 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 a rem dichiarazione (funziona anche con %2 .. %*).
Quindi anche "&"& potrebbe essere ripetuto senza produrre un errore, come viene osservato.

Ma per essere in grado di reindirizzare l'output di echo on, sono necessari i due cicli for.

I personaggi extra * # sono usati per essere sicuri contro contenuti come /? (mostrerebbe l'aiuto per REM).
Oppure un accento circonflesso ^ alla fine della riga potrebbe funzionare come carattere su più righe, anche dopo a rem.

Poi leggendo il parametro rem output dal file, ma con attenzione.
Il per /f dovrebbe funzionare con l'espansione ritardata, altrimenti con "!" sarebbe distrutto.
Dopo aver rimosso i caratteri extra in param1, avete capito bene.

E da usare param1 in modo sicuro, abilitare l'espansione ritardata.

Sì, e non dimenticare di usare variabili come %%1 quando si usa if E for e la banda.

Se dimentichi il doppio %, allora sostituirai gli argomenti della riga di comando (possibilmente null) e riceverai alcuni messaggi di errore piuttosto confusi.

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 ciò che ha fatto il file batch e attende che tu prema il tasto QUALSIASI.Salvalo come xx.bat nella cartella Windows.

Per utilizzarlo digitare, ad esempio:

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

Questo file batch si occupa di tutti i parametri necessari, come copiare solo i file, quelli più recenti, ecc.Lo uso da prima di Windows.Se ti piace vedere i nomi dei file mentre vengono copiati, tralascia il file Q parametro.

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

Nota:SE "%1"=="" causerà problemi se %1 è racchiuso tra virgolette.

In tal caso, utilizzare IF [%1]==[] oppure, solo in NT 4 (SP6) e versioni successive, IF "%~1"=="" Invece.

Recentemente un amico mi ha chiesto informazioni su questo argomento, quindi ho pensato di pubblicare come gestisco gli argomenti della riga di comando nei file batch.

Come vedrai, questa tecnica comporta un po' di sovraccarico, ma rende i miei file batch molto facili da comprendere e rapidi da implementare.Oltre a supportare le seguenti strutture:

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

Il succo è avere il :init, :parse, E :main funzioni.

Utilizzo di esempio

>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"

modello.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

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%

Ecco 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 esegue il loop sui parametri batch (%*) che siano tra virgolette o meno, quindi visualizza ciascun parametro.

Ho scritto un semplice script read_params che può essere chiamato come funzione (o external .bat) e inserirà tutte le variabili nell'ambiente corrente.Non modificherà i parametri originali perché la funzione è in corso called 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 utilizzare 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

  • Impossibile caricare argomenti senza valore come -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.

Registro delle modifiche

  • 2/18/2016
    • Non richiede più un'espansione ritardata
    • Ora funziona con altri argomenti della riga di comando cercando - prima dei parametri.

Per fare riferimento a una variabile impostata nella riga di comando è necessario utilizzare %a% quindi ad esempio:

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

Nota:Funziona con Windows 7 pro.

Crea un nuovo file batch (esempio:openclass.bat) e scrivere questa riga nel file:

java %~n1

Quindi posiziona il file batch, diciamo, nella cartella system32, vai al file della classe Java, fai clic con il pulsante destro del mouse, Proprietà, Apri con..., quindi trova il file batch, selezionalo e il gioco è fatto...

Per me funziona.

PS:Non riesco a trovare un modo per chiudere la finestra cmd quando chiudo la classe Java.Per adesso...

Ispirato da un rispondere altrove di @Jon, ho creato un algoritmo più generale per estrarre parametri denominati, valori opzionali e opzioni.

Diciamo che vogliamo implementare un'utilità foobar.Richiede un comando iniziale.Ha un parametro facoltativo --foo che richiede un opzionale valore (che ovviamente non può essere un altro parametro);se manca il valore, il valore predefinito è default.Ha anche un parametro opzionale --bar che richiede a necessario valore.Infine può prendere una bandiera --baz senza valore consentito.Oh, e questi parametri possono essere presenti in qualsiasi ordine.

In altre parole, assomiglia a questo:

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
  • Utilizzo SETLOCAL in modo che le variabili non fuoriescano nell'ambiente chiamante.
  • Non dimenticare di inizializzare le variabili SET FOO=, eccetera.nel caso qualcuno li definisse nell'ambiente chiamante.
  • Utilizzo %~1 per rimuovere le virgolette.
  • Utilizzo IF "%ARG%" == "" e non IF [%ARG%] == [] Perché [ E ] non riprodurre affatto will con valori che terminano con uno spazio.
  • Anche se tu SHIFT all'interno di un IF blocco, gli argomenti attuali come %~1 non vengono aggiornati perché vengono determinati quando il file IF viene analizzato.Potresti usare %~1 E %~2 dentro il IF blocco, ma creerebbe confusione perché avevi un file SHIFT.Potresti mettere il SHIFT alla fine del blocco per chiarezza, ma anche questo potrebbe perdersi e/o confondere le persone.Quindi "catturare" %~1 E %~1 fuori dal blocco sembra migliore.
  • Non vuoi utilizzare un parametro al posto del valore facoltativo di un altro parametro, quindi devi controllare IF NOT "%ARG:~0,2%" == "--".
  • Fai attenzione solo a SHIFT quando tu utilizzo uno dei parametri.
  • Il codice duplicato SET FOO=%DEFAULT_FOO% è deplorevole, ma l'alternativa sarebbe aggiungere un IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% fuori da IF NOT "%ARG%" == "" bloccare.Tuttavia poiché questo è ancora all'interno del file IF "%PARAM%" == "--foo" blocco, il %FOO% value sarebbe stato valutato e impostato prima che tu entrassi nel blocco, quindi non lo rileveresti mai Entrambi IL --foo il parametro era presente e anche che il %FOO% mancava il valore.
  • Notare che ECHO Missing bar value. 1>&2 invia il messaggio di errore a stderr.
  • Vuoi una riga vuota in un file batch di Windows?Devi usare ECHO: o una delle varianti.

Soluzione semplice (anche se la domanda è vecchia)

Prova1.bat

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

ChiamaTest1.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, memorizza il comando param nella variabile e usa la variabile per il confronto.

Non è solo semplice da scrivere, ma è anche semplice da mantenere, quindi se in seguito qualcun altro o tu leggessi la tua sceneggiatura dopo un lungo periodo di tempo, sarà facile da capire e mantenere.

Per scrivere il codice in linea:vedi altre risposte.

enter image description here

Per utilizzare il loop ottieni tutti gli argomenti e in batch puro:

@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 

Il tuo codice è pronto per fare qualcosa con il numero di argomento dove necessario, come...

 @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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top