Bir toplu iş dosyasını başlatırken / çağırırken bir bağımsız değişkenin tanımlanıp tanımlanmadığını nasıl kontrol edebilirim?


99

Bir toplu iş dosyasında aşağıdaki doğrulama mantığını kullanmaya çalışıyorum, ancak "kullanım" bloğu, toplu iş dosyasına hiçbir parametre sağlanmadığında bile hiçbir zaman yürütülmüyor.

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

@echo This should not execute

@echo Done.
goto :eof

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

Neyi yanlış yapıyorum?



1
@ double-beep - Buradaki soru (daniel-fortunov tarafından), bahsettiğiniz soru gönderilmeden yaklaşık bir yıl önce soruldu. (Olası) kopya hangisi?
Kevin Fegan

1
@KevinFegan çünkü diğer sorunun daha fazla görüş ve daha fazla yanıtı var.
çift ​​bip sesi

Yanıtlar:


150

Bir komut satırı bağımsız değişkeninin ayarlanıp ayarlanmadığını kontrol etmek mümkündür [%1]==[], ancak Dave Costa'nın da işaret ettiği gibi , "%1"==""aynı zamanda çalışacaktır.

Ayrıca büyüktür ve küçüktür işaretlerinden kaçmak için kullanım yankısındaki bir sözdizimi hatasını düzelttim. Ek olarak, exitihtiyaçlar bir /Bargüman aksi CMD.exetakdirde bırakacaktır.

@echo off

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

19
[% 1] == [], "% 1" == "" den daha iyidir çünkü% 1'in kendisinin çift tırnak içerdiği durumu doğru şekilde ele alır. "% 1" == "", "şu anda beklenmedik" mesajıyla hata verecek.
tekumara

2
Komut satırı bağımsız değişkenlerini değil de setdeğişkenleri kullanıyorsanız (doğru toplu iş terminolojisini bilmiyorum), kullanmak isteyebileceğinizi unutmayın, "%myvar%"==""çünkü myvariçinde boşluklar varsa ve tırnak işaretlenmemişse, şu anda "beklenmedik" " İleti.
Pat

1
@Pat SET değişkenleri IF NOT DEFINED VarNameblok ile kontrol edilebilir . Ayrıca karşılaştırmada alıntı kullanmadığı için tukushan'a +1. Sadece yapma. Asla.
Fr0sT

11
"%~1"==""% 1'in çift
tırnağı

9
"%~1"==""değişkendeki boşlukları işler, []sürümde değil.
Cookie Butter

18

Daha gelişmiş bir örnek:

⍟ sınırsız argümanlar.

⍟ dosya sisteminde (ya fileda directory?) Ya da genel string.

⍟ dosya olup olmadığını belirtin

⍟ bir dizin olduğunu belirtin

⍟ uzantı yok , eski komut dosyalarında çalışır!

minimum kod ☺

@Eko kapalı

: döngü
      :: -------------------------- argüman mı var?
      ["% ~ 1"] == [""] (
        yankı bitti.
        sona git
      )
      :: -------------------------- argüman var mı?
      yoksa% ~ s1 (
        yankı yok
      ) Başka (
        yankı var
        % ~ s1 \ NUL (
          echo bir dizindir
        ) Başka (
          echo bir dosyadır
        )
      )
      :: --------------------------
      vardiya
      döngüye git
      
      
:son

Duraklat

✨ diğer şeyler..✨

■ in %~1- ~herhangi bir ambalajı kaldırır "veya '.

■ in %~s1- the s, yolun olmasını sağlar DOS 8.3 naming; bu, öğeleri kontrol ederken dosya adında boşluklardan kaçınmak için güzel bir yöntemdir (ve bu şekilde, kaynağı daha fazla URL ile sarmaya gerek kalmaz ".

["%~1"]==[""]bağımsız değişken bir dosya / dizin veya sadece genel bir dize ise "emin olamıyorum", bu nedenle ifade parantezler ve orijinal değiştirilmemiş %1( "eğer varsa ..)

Eğer kullanmış olsaydık shiftve arg-list işaretçisi sonuncuyu geçtiyse, herhangi bir argüman yoksa , ifade değerlendirilecektir [""]==[""].

■ bu, daha fazla numara kullanmadan yapabileceğiniz kadar spesifiktir (Windows 95'in toplu komut dosyalarında bile çalışır ...)

■ yürütme örnekleri

farklı kaydet identifier.cmd

sınırsız argümanları tanımlayabilir (normalde %1- ile sınırlandırılırsınız %9), argümanları ters virgülle sarmayı veya 8.3 adlandırma kullanmayı veya bunları sürükleyip bırakmayı unutmayın (yukarıdakilerden herhangi birini otomatik olarak yapar).


bu, aşağıdaki komutları çalıştırmanıza izin verir:

identifier.cmd c:\windows ve almak

var olmak
bir dizindir
bitti

identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" ve almak

var olmak
bir dosyadır
bitti

⓷ ve birden fazla argüman (elbette tüm anlaşma budur ..)

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

ve almak

var olmak
bir dizindir
var olmak
bir dosyadır
var olmak
bir dosyadır
yok
bitti.

doğal olarak çok daha karmaşık olabilir, ancak güzel örnekler her zaman basit ve asgari düzeyde olmalıdır. :)

Umarım herkese yardımcı olur :)

burada yayınlandı: CMD Ninja - Sınırsız Bağımsız Değişken İşleme, Dosya Sisteminde Varsa Tanımlama, Dosya Veya Dizin Olup Olmadığını Tanımlama

ve işte herhangi bir miktarda APK dosyası (Android uygulamaları) alan ve bunları hata ayıklama konsolu (ADB.exe) aracılığıyla cihazınıza yükleyen çalışan bir örnek: Önceki Yazıyı ADB Install-Multi Sözdizimini Kullanmayan Bir Toplu APK Yükleyicisi Yapın


14

Parantezlerden kurtulun.

Örnek toplu iş dosyası:

echo "%1"

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

if "%1"=="" echo match2

Yukarıdaki komut dosyasını çalıştırmanın sonucu:

C:\>echo "" 
""

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

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

Sanırım aslında parantezleri dizelerin bir parçası olarak alıyor ve karşılaştırılıyorlar.


1
if "%1"==""arg'de boşluklar varsa çökecektir. Örneğin: run.bat "a b". @amr kullanılacak en iyi yanıta sahipif "%~1"==""
wisbucky

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

~% 1'in kendisi alıntılanmışsa,% 1'in teklifini kaldırır.

"" geçen özel karakterlerden koruyacaktır. örneğin komut dosyasını & ping ile çağırmak


1
Bu en iyi cevap. Diğer cevaplar bazı durumlarda işe run.bat "a b"
yarar

@wisbucky Bu kadar karmaşa görünmüyor kabul cevap . Neyi kaçırıyorum?
2017

@ruffin, Örnek: run.bat ""ile yakalanmayacak [%1]==[].
akıllıca


2

Bu, diğer yanıtlarla aynıdır, ancak yalnızca bir etiket kullanır ve kullanımı ilk sıraya koyar, bu da onu, genellikle en üste yerleştirilen, betiğin bir tür dokümantasyon önerisi olarak hizmet etmesini sağlar:

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

Bununla birlikte, cmd / batch kullanmak zorunda değilseniz, WSL veya powershell üzerinde bash kullanın, daha mantıklı sözdizimleri ve daha az gizli özelliklere sahiptirler.


0

EĞER "% 1" == "" başarısız olursa, bunun tüm sürümleri belirli zehirli karakter koşulları altında başarısız olur. Yalnızca TANIMLANMIŞSA veya TANIMLANMADIYSA güvenlidir


if [not] defined ...gibi parametrelerle çalışmaz %1. Bir örneğiniz var mı, nerede if "%~1" ...çalışmıyor?
Stephan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.