Eu preciso testar se uma variável está definida ou não. Eu tentei várias técnicas, mas eles parecem falhar sempre que %1
é cercada por citações como é o caso quando %1
é "c:\some path with spaces"
.
IF NOT %1 GOTO MyLabel // This is invalid syntax
IF "%1" == "" GOTO MyLabel // Works unless %1 has double quotes which fatally kills bat execution
IF %1 == GOTO MyLabel // Gives an unexpected GOTO error.
De acordo com este site , esses são os IF
tipos de sintaxe suportados . Então, não vejo uma maneira de fazer isso.
IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command
windows
shell
batch-file
cmd
blak3r
fonte
fonte
if "%1" == "" GOTO MyLabel
não mata fatalmente a execução do script, desde que%1
tenha um número par de aspas duplas. Vejo que um número ímpar de aspas duplas%1
mata a execução do script com este erro:The syntax of the command is incorrect.
A solução abaixo, que usa colchetes para resolver o problema, foi marcada como a resposta correta, mas parece que não está melhorando. . Essa solução também falha com o mesmo erro quando%1
há um número ímpar de aspas duplas.IF DEFINED
trabalhar apenas em variáveis de ambiente em vez de variáveis de script é um desperdício de potencial!Respostas:
Use colchetes em vez de aspas:
Os parênteses são inseguros : use apenas colchetes.
fonte
&
no%1
vai quebrar a linhaif #%1#==##
ouif [%1]==[]
é bom, desde que não haja espaços no argumento, caso contrário, você receberá um…was unexpected at this time
erro."%~1"
é realmente uma abordagem melhor, como mencionei na minha resposta.==
. Use a resposta dele.it DOES NOT work with spaces
. Use a resposta @jamesdlin.Você pode usar:
para retirar o conjunto externo de aspas. Em geral, esse é um método mais confiável do que usar colchetes, porque funcionará mesmo que a variável tenha espaços.
fonte
~
, você tira as aspas externas, se estiverem presentes, mas depois as adiciona manualmente (garantindo apenas um conjunto). Além disso, você tem de usar aspas se o argumento contém espaços (Eu aprendi isso da maneira mais difícil quando a minha versão anterior do uso de#
argumentos ou suportes em vez de aspas causado com espaços para lançar um…was unexpected at this time
erro.)""this string will crash the comparison""
Double '"' é a sequência de escape adequada e fazer uma substituição em double '"' falhará se o A string está vazia."%~1"
.Uma das melhores soluções semi é copiar
%1
para uma variável e usar a expansão atrasada, como delayedExp. está sempre seguro contra qualquer conteúdo.A vantagem disso é que lidar com o param1 é absolutamente seguro.
E a configuração do param1 funcionará em muitos casos, como
Mas ainda falha com conteúdos estranhos como
Ser capaz de obter uma resposta 100% correta para a existência
Ele detecta se
%1
está vazio, mas, para alguns conteúdos, não pode buscá-lo.Isso também pode ser útil para distinguir entre um vazio
%1
e outro com""
.Ele usa a capacidade do
CALL
comando falhar sem interromper o arquivo em lotes.Se você deseja ser 100% à prova de balas para buscar o conteúdo, pode ler Como receber até os parâmetros mais estranhos da linha de comando?
fonte
De IF / ?:
fonte
%1
e para os gostos. "Variáveis definidas dentro do arquivo em lotes" são na verdade variáveis de ambiente enquanto o arquivo em lote está em execução, e você pode usáIF DEFINED
-las.Infelizmente, não tenho reputação suficiente para comentar ou votar nas respostas atuais, pois tive que escrever minhas próprias.
Originalmente, a pergunta do OP dizia "variável" em vez de "parâmetro", o que ficou muito confuso, especialmente porque esse era o link número um no google para pesquisar como testar variáveis em branco. Desde a minha resposta original, Stephan editou a pergunta original para usar a terminologia correta, mas em vez de excluir minha resposta, decidi deixá-la para ajudar a esclarecer qualquer confusão, especialmente no caso do Google ainda enviar pessoas aqui para variáveis também:
% 1 NÃO É VARÁVEL! É UM PARÂMETRO DE LINHA DE COMANDO.
Distinção muito importante. Um único sinal de porcentagem com um número depois que se refere a um parâmetro de linha de comando e não a uma variável.
As variáveis são definidas usando o comando set e são recuperadas usando sinais de 2 por cento - um antes e um depois. Por exemplo% myvar%
Para testar uma variável vazia, use a sintaxe "se não definida" (os comandos explicitamente para variáveis não requerem sinais de porcentagem), por exemplo:
(Se você quiser testar os parâmetros da linha de comando, recomendo consultar a resposta de jamesdlin.)
fonte
if variable is empty
paraif parameter is empty
. Eu acabei de fazer isso. (com o risco de invalidar algumas das respostas, que fizeram variáveis cheque em vez de parâmetros e por isso são de qualquer maneira inválida, uma vez que não respondeu a pergunta)Use "IF variável comando" para testar a variável no arquivo em lotes.
Mas se você quiser testar os parâmetros em lote, tente os códigos abaixo para evitar entradas complicadas (como "1 2" ou ab ^> cd)
fonte
Eu testei com o código abaixo e está tudo bem.
fonte
IF DEFINED var
por uma razãoEu costumo usar isso:
Se% 1 estiver vazio, o FI comparará "." para "." que avaliará como verdadeiro.
fonte
Criei esse pequeno script em lote com base nas respostas aqui, pois existem muitas válidas. Sinta-se à vontade para adicionar isso, desde que você siga o mesmo formato:
fonte
String vazia é um par de
double-quotes
/""
, podemos apenas testar o comprimento:então teste 2 caracteres contra
double-quotes
:Aqui está um script em lote com o qual você pode jogar. Eu acho que pega corretamente a corda vazia.
Este é apenas um exemplo, você só precisa personalizar 2 (ou 3?) Etapas acima, de acordo com o seu script.
Este resultado do teste de tortura:
fonte
""
uma string vazia é uma string vazia `` e no lote uma variável vazia é uma variável indefinida. Você pode definir que, para seus argumentos, as aspas externas serão removidas, mas a sequência ainda estará vazia com um comprimento de 0""
são usados para cadeias vazias, mas é muito fácil%~1
de remover as aspas externas. não há necessidade de usar uma solução tão complexa"%~1"==""
falharão com argumentos como"Long File Name".txt
qual é um argumento válido. edit : E definitivamente não é complexo como você disse. Apenas 2 etapas acima para o teste, o restante é um exemplo detalhado.Você pode usar
fonte
Script 1:
Entrada ("Remover Quotes.cmd" "Este é um teste")
Saída (não há,% 1 NÃO estava em branco, vazio ou NULL):
Execute ("Remove Quotes.cmd") sem nenhum parâmetro com o script acima 1
Saída (% 1 está em branco, vazio ou NULL):
Nota: Se você definir uma variável dentro de um
IF ( ) ELSE ( )
instrução, ela não estará disponível para DEFINED até que saia da instrução "SE" (a menos que a opção "Expansão atrasada da variável" esteja ativada; uma vez ativado, use um ponto de exclamação "!" No lugar do símbolo de porcentagem "%"}.Por exemplo:
Script 2:
Entrada ("Remover Quotes.cmd" "Este é um teste")
Resultado:
Nota: Ele também removerá aspas de dentro da string.
Por exemplo (usando o script 1 ou 2): C: \ Usuários \ Teste \ Documentos \ Arquivos em lote> "Remover Quotes.cmd" "Este é" um "Teste"
Saída (Script 2):
Execute ("Remove Quotes.cmd") sem nenhum parâmetro no Script 2:
Resultado:
fonte
Para resumir:
Esse código exibirá "String vazia" se% 1 estiver "" ou "ou vazio. Adicionado à resposta aceita que está incorreta no momento.
fonte
Eu tive muitos problemas com muitas respostas na rede. A maioria funciona para a maioria das coisas, mas sempre há uma caixa de canto que quebra cada uma.
Talvez não funcione se tiver aspas, talvez quebre se não tiver aspas, erro de sintaxe se o var tiver um espaço, alguns funcionarão apenas em parâmetros (ao contrário de variáveis de ambiente), outras técnicas permitem um vazio conjunto de aspas para passar como 'definido', e algumas mais complicadas não permitirão que você encadeie
else
depois.Aqui está uma solução que eu estou feliz com, por favor me avise se você encontrar uma caixa de esquina para a qual não funcionará.
Ter essa sub-rotina no seu script ou no seu
.bat
deve funcionar.Então, se você quiser escrever (em pseudo):
Você pode escrever:
Funcionou em todos os meus testes:
Echo'd
n
,y
,n
,y
,y
Mais exemplos:
if
?Call :ifSet %var% && Echo set
Call :ifSet %var% || Echo set
Call :ifSet %1 && Echo set
ifSet.bat
? Sem problemas:((Call ifSet.bat %var%) && Echo set) || (Echo not set)
fonte
(Call ifSet.bat YES && (Echo true & Echo x | findstr y)) || Echo
true
false
ifSet
por conta própria, em seguida, usandoIf %errorlevel% EQU 0 (x) Else (y)
set
variáveis (como[%bob%]
, apenas trabalhando para argumentos como[%2]
), mas agora verificando novamente como funciona. Eu acho que a minha única queixa com[]
agora é ele permite aspas vazias passar, enquanto isso não vai (por isso é até para o seu caso de uso, realmente)/B
sinalizador impede a saída do lote inteiro, saindo apenas da sub-rotina oucall
do lote. A menos que você esteja perguntando o que todo o comando está fazendo; ele está retornando um código de erro de deixar o script chamado saber o resultado da sub-rotina (0
passagem,1
falha), utilizáveis lógica booleana via na resposta, ou via%errorlevel%
nos comentários acimaUsando! em vez de "para verificação de string vazia
fonte
Eu entrei com menos de um mês (apesar de ter sido solicitado há 8 anos) ... Espero que ele já tenha passado dos arquivos em lotes. ;-) Eu costumava fazer isso o tempo todo. Não tenho certeza de qual é o objetivo final. Se ele é preguiçoso como eu, meu go.bat funciona para coisas assim. (Veja abaixo) Mas, 1, o comando no OP pode ser inválido se você estiver usando diretamente a entrada como um comando. ou seja,
é um comando inválido (ou costumava ser se você estivesse em uma unidade diferente). Você precisa dividi-lo em duas partes.
E, 2, o que significa 'definido' ou 'indefinido'? GIGO. Eu uso o padrão para detectar erros. Se a entrada não for capturada, ela será removida para ajudar (ou um comando padrão). Portanto, nenhuma entrada não é um erro. Você pode tentar cd para a entrada e capturar o erro, se houver um. (Ok, usar go "downloads (apenas um paren) é capturado pelo DOS. (Harsh!))
E, 3, aspas são necessárias apenas no caminho, não no comando. ou seja,
era ruim (ou costumava ser antigamente), a menos que você estivesse em uma unidade diferente.
é funcional.
funciona se você tiver espaços no seu caminho.
fonte
cd
o/d
switch:cd /d "C:\Users\Me" (and the proper path delimeter for Windows is
`, not/
).