¿Cómo puedo verificar si un argumento está definido al iniciar / llamar a un archivo por lotes?

96

Estoy tratando de usar la siguiente lógica de validación en un archivo por lotes, pero el bloque "uso" nunca se ejecuta incluso cuando no se proporciona ningún parámetro al archivo por lotes.

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

@echo This should not execute

@echo Done.
goto :eof

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

¿Qué estoy haciendo mal?

Daniel Fortunov
fuente

Respuestas:

146

La verificación de si se ha establecido un argumento de línea de comandos puede ser [%1]==[], pero, como señala Dave Costa , también funcionará."%1"==""

También solucioné un error de sintaxis en el eco de uso para escapar de los signos mayor que y menor que. Además, la exitnecesidad de un /Bargumento de lo contrario se CMD.execerrará.

@echo off

if [%1]==[] goto usage
@echo This should not execute
@echo Done.
goto :eof
:usage
@echo Usage: %0 ^<EnvironmentName^>
exit /B 1
Iain
fuente
18
[% 1] == [] es mejor que "% 1" == "" porque manejará correctamente el caso en el que% 1 contenga comillas dobles. "% 1" == "" generará un error con un mensaje "inesperado en este momento".
tekumara
2
Tenga en cuenta que, si no está usando argumentos de línea de comandos sino setvariables (no sé la terminología de lote correcta), es posible que desee usar "%myvar%"==""porque si myvartiene espacios y no está entre comillas, obtendrá el "inesperado en este momento "mensaje.
Pat
1
Las variables @Pat SET se pueden verificar con IF NOT DEFINED VarNameblock. También +1 a tukushan por no usar comillas en comparación. Simplemente no lo hagas. Nunca.
Viernes
10
"%~1"==""también funcionará y se ocupará del caso en el que% 1 tenga comillas dobles
Drakkim
8
"%~1"==""maneja espacios en la variable mientras que la []versión no.
Mantequilla de galleta
17

Un ejemplo más avanzado:

⍟ argumentos ilimitados.

⍟ existe en el sistema de archivos ( ¿ fileo directory?) O genérico string.

⍟ especificar si es un archivo

⍟ especificar es un directorio

sin extensiones, ¡funcionaría en scripts heredados!

código mínimo ☺

@echo apagado

:lazo
      :: -------------------------- tiene argumento?
      si ["% ~ 1"] == [""] (
        echo hecho.
        ir al final
      )
      :: -------------------------- argumento existe?
      si no existe% ~ s1 (
        eco no existe
      ) más (
        el eco existe
        si existe% ~ s1 \ NUL (
          echo es un directorio
        ) más (
          echo es un archivo
        )
      )
      :: --------------------------
      cambio
      Ir a bucle
      
      
:final

pausa

✨ otras cosas..✨

■ en %~1: ~elimina cualquier envoltorio "o '.

■ in %~s1- the shace que la ruta sea DOS 8.3 naming, lo cual es un buen truco para evitar espacios en el nombre de archivo mientras verifica cosas (y de esta manera no es necesario envolver el recurso con más "s.

■ el ["%~1"]==[""]"no puedo estar seguro" si el argumento es un archivo / directorio o simplemente una cadena genérica todavía, por lo que en su lugar la expresión usa corchetes y el original sin modificar %1(solo sin el "ajuste, si lo hay ..)

si no hubo argumentos de si lo hemos usado shifty el puntero de lista de argumentos ha pasado el último, la expresión se evaluará como [""]==[""].

■ esto es lo más específico que puede ser sin usar más trucos (funcionaría incluso en los scripts por lotes de Windows-95 ...)

■ ejemplos de ejecución

guárdalo como identifier.cmd

puede identificar un número ilimitado de argumentos (normalmente está limitado a %1- %9), solo recuerde envolver los argumentos con comas invertidas, o use la denominación 8.3, o arrástrelos y suéltelos (automáticamente hace cualquiera de los anteriores).


esto le permite ejecutar los siguientes comandos:

identifier.cmd c:\windows y para conseguir

existe
es un directorio
hecho

identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" y para conseguir

existe
es un archivo
hecho

⓷ y múltiples argumentos (por supuesto, este es el problema ..)

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

y conseguir

existe
es un directorio
existe
es un archivo
existe
es un archivo
no existe
hecho.

naturalmente, puede ser mucho más complejo, pero los buenos ejemplos siempre deben ser simples y mínimos. :)

Espero que ayude a alguien :)

publicado aquí: CMD Ninja - Procesamiento ilimitado de argumentos, identificación de si existe en el sistema de archivos, identificación de archivo o directorio

y aquí hay un ejemplo de trabajo que toma cualquier cantidad de archivos APK (aplicaciones de Android) y los instala en su dispositivo a través de la consola de depuración (ADB.exe): Haga de la publicación anterior un instalador masivo de APK que no use ADB Install-Multi Syntax

Comunidad
fuente
14

Deshazte de los paréntesis.

Archivo por lotes de muestra:

echo "%1"

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

if "%1"=="" echo match2

Resultado de ejecutar el script anterior:

C:\>echo "" 
""

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

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

Creo que en realidad está tomando los paréntesis para ser parte de las cadenas y se están comparando.

Dave Costa
fuente
1
if "%1"==""se bloqueará si el argumento tiene espacios. Por ejemplo: run.bat "a b". @amr tiene la mejor respuesta para usarif "%~1"==""
wisbucky
6
IF "%~1"=="" GOTO :Usage

~ eliminará% 1 si se cita% 1.

"" protegerá de los caracteres especiales pasados. por ejemplo llamando al script con & ping

Amr Ali
fuente
1
Esta es la mejor respuesta. Las otras respuestas funcionan para algunos casos, pero fallarán para los casos más especiales comorun.bat "a b"
wisbucky
@wisbucky Eso no parece estropear la respuesta aceptada . ¿Qué me estoy perdiendo?
Ruffin
@ruffin, Ejemplo: run.bat ""no será atrapado por [%1]==[].
wisbucky
2
IF "%1"=="" GOTO :Continue
.....
.....
:Continue
IF "%1"=="" echo No Parameter given
Howard Rothenburg
fuente
Esto se bloquea pararun.bat "a b"
wisbucky
2

Esto es lo mismo que las otras respuestas, pero usa solo una etiqueta y pone el uso primero, lo que además hace que sirva como una especie de recomendación de documentación del script que generalmente también se coloca en la parte superior:

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

Sin embargo, si no tiene que usar cmd / batch, use bash en WSL o powershell, tienen una sintaxis más sana y menos características arcanas.

masterxilo
fuente
0

SI "% 1" == "" fallará, todas las versiones fallarán bajo ciertas condiciones de carácter venenoso. Solo SI ESTÁ DEFINIDO o NO ESTÁ DEFINIDO son seguros

codey
fuente
if [not] defined ...no funciona con parámetros como %1. ¿Tiene un ejemplo, dónde if "%~1" ...no funciona?
Stephan