Come posso verificare se un argomento è definito quando si avvia / richiama un file batch?


97

Sto cercando di utilizzare la seguente logica di convalida in un file batch, ma il blocco "utilizzo" non viene mai eseguito anche quando non viene fornito alcun parametro al file batch.

if ("%1"=="") goto usage

@echo This should not execute

@echo Done.
goto :eof

:usage
@echo Usage: %0 <EnvironmentName>
exit 1

Che cosa sto facendo di sbagliato?



@ double-beep - La domanda qui (di daniel-fortunov) è stata posta per prima, circa un anno prima che la domanda a cui ti riferisci fosse pubblicata. Qual è il (possibile) duplicato?
Kevin Fegan

@KevinFegan perché l'altra domanda ha più visualizzazioni e più risposte.
doppio segnale acustico il

Risposte:


147

Il controllo per verificare se un argomento della riga di comando è stato impostato può essere [%1]==[], ma, come sottolinea Dave Costa , funzionerà anche."%1"==""

Ho anche corretto un errore di sintassi nell'eco di utilizzo per sfuggire ai segni di maggiore e minore di. Inoltre, ha exitbisogno di un /Bargomento altrimenti CMD.exeverrà chiuso.

@echo off

if [%1]==[] goto usage
@echo This should not execute
@echo Done.
goto :eof
:usage
@echo Usage: %0 ^<EnvironmentName^>
exit /B 1

18
[% 1] == [] è meglio di "% 1" == "" perché gestirà correttamente il caso in cui% 1 stesso contiene virgolette doppie. "% 1" == "" restituirà un errore con un messaggio "inaspettato in questo momento".
tekumara

2
Nota che, se non stai usando argomenti della riga di comando ma setvariabili (non conosco la terminologia batch corretta), potresti volerlo usare "%myvar%"==""perché se myvarcontiene spazi e non è quotato, otterrai il "inaspettato in questo momento " Messaggio.
Pat

1
Le variabili @Pat SET possono essere controllate con il IF NOT DEFINED VarNameblocco. Anche +1 a tukushan per non aver usato le virgolette in confronto. Basta non farlo. Mai.
venerdì

10
"%~1"==""funzionerà anche e si prenderà cura del caso in cui% 1 ha virgolette doppie
Drakkim

8
"%~1"==""gestisce gli spazi nella variabile mentre la []versione no.
Cookie Butter

17

Un esempio più avanzato:

⍟ argomenti illimitati.

⍟ esistono su file system (o fileo directory?) O generico string.

⍟ specificare se è un file

⍟ specificare è una directory

nessuna estensione, funzionerebbe negli script legacy!

codice minimo ☺

@echo off

:ciclo continuo
      :: -------------------------- ha argomento?
      se ["% ~ 1"] == [""] (
        eco fatto.
        vai alla fine
      )
      :: -------------------------- argomento esiste?
      se non esiste% ~ s1 (
        l'eco non esiste
      ) altro (
        l'eco esiste
        se esiste% ~ s1 \ NUL (
          echo è una directory
        ) altro (
          echo è un file
        )
      )
      :: --------------------------
      cambio
      goto loop
      
      
:fine

pausa

✨ altre cose ..

■ in %~1- ~rimuove qualsiasi involucro "o '.

■ in %~s1- srende il percorso DOS 8.3 naming, che è un bel trucco per evitare spazi nel nome del file durante il controllo delle cose (e in questo modo non c'è bisogno di racchiudere la risorsa con più "s.

["%~1"]==[""]"non posso essere sicuro" se l'argomento è ancora un file / directory o solo una stringa generica, quindi invece l'espressione usa le parentesi e l'originale non modificato %1(solo senza il "wrapping, se presente ..)

se non ci fossero argomenti di if abbiamo usato shifte il puntatore alla lista degli argomenti ha passato l'ultimo, l'espressione sarà valutata a [""]==[""].

■ questo è tanto specifico che puoi essere senza usare più trucchi (funzionerebbe anche negli script batch di Windows-95 ...)

■ esempi di esecuzione

salvalo come identifier.cmd

può identificare un numero illimitato di argomenti (normalmente sei limitato a %1- %9), ricorda solo di racchiudere gli argomenti tra virgolette, o usare i nomi 8.3, o trascinarli sopra (fa automaticamente uno dei due precedenti).


questo ti permette di eseguire i seguenti comandi:

identifier.cmd c:\windows e per ottenere

esistere
è una directory
fatto

identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" e per ottenere

esistere
è un file
fatto

⓷ e più argomenti (ovviamente questo è l'intero affare ..)

identifier.cmd c:\windows\system32 c:\hiberfil.sys "c:\pagefile.sys" hello-world

e per ottenere

esistere
è una directory
esistere
è un file
esistere
è un file
non esiste
fatto.

naturalmente può essere molto più complesso, ma i begli esempi dovrebbero essere sempre semplici e minimali. :)

Spero che aiuti chiunque :)

pubblicato qui: CMD Ninja - Elaborazione illimitata di argomenti, identificazione se esiste nel file system, identificazione se file o directory

ed ecco un esempio funzionante che prende qualsiasi quantità di file APK (app Android) e li installa sul tuo dispositivo tramite debug-console (ADB.exe): Rendi il post precedente un programma di installazione APK di massa che non utilizza ADB Install-Multi sintassi


14

Elimina le parentesi.

File batch di esempio:

echo "%1"

if ("%1"=="") echo match1

if "%1"=="" echo match2

Output dall'esecuzione dello script precedente:

C:\>echo "" 
""

C:\>if ("" == "") echo match1 

C:\>if "" == "" echo match2 
match2

Penso che in realtà stia prendendo le parentesi per essere parte delle stringhe e vengono confrontate.


1
if "%1"==""si bloccherà se l'argomento ha spazi. Ad esempio: run.bat "a b". @amr ha la migliore risposta da usareif "%~1"==""
wisbucky

6
IF "%~1"=="" GOTO :Usage

~ rimuoverà% 1 se% 1 viene citato.

"" proteggerà dai caratteri speciali passati. ad esempio chiamando lo script con & ping


1
Questa è la migliore risposta. Le altre risposte funzionano per alcuni casi, ma falliranno per casi più speciali comerun.bat "a b"
wisbucky

@wisbucky Questo non sembra rovinare la risposta accettata . Cosa mi sto perdendo?
ruffin

@ruffin, Esempio: run.bat ""non verrà catturato con [%1]==[].
wisbucky


2

Questa è la stessa delle altre risposte, ma usa solo un'etichetta e mette prima l'uso, il che lo rende inoltre una sorta di documentazione dello script che di solito è anche posizionato in alto:

@echo off
:: add other test for the arguments here...
if not [%1]==[] goto main
:: --------------------------
echo This command does something.
echo.
echo %0 param%%1 param%%2
echo       param%%1 the file to operate on
echo       param%%1 another file

:: --------------------------
exit /B 1

:main
:: --------------------------
echo do something with all arguments (%%* == %*) here...

Tuttavia, se non è necessario utilizzare cmd / batch, utilizzare bash su WSL o PowerShell, hanno una sintassi più sana e funzionalità meno arcane.


0

SE "% 1" == "" fallirà, tutte le versioni di questo falliranno in determinate condizioni di carattere avvelenato. Solo SE DEFINITO o SE NON DEFINITO sono sicuri


if [not] defined ...non funziona con parametri come %1. Hai un esempio, dove if "%~1" ...non funziona?
Stephan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.