Làm cách nào để kiểm tra xem một đối số có được xác định khi bắt đầu / gọi một tệp loạt không?


96

Tôi đang cố gắng sử dụng logic xác thực sau trong tệp lô nhưng khối "sử dụng" không bao giờ thực thi ngay cả khi không có tham số nào được cung cấp cho tệp lô.

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

@echo This should not execute

@echo Done.
goto :eof

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

Tôi đang làm gì sai?


Câu trả lời:


146

Việc kiểm tra xem đối số dòng lệnh đã được thiết lập hay chưa [%1]==[], nhưng như Dave Costa chỉ ra , "%1"==""cũng sẽ hoạt động.

Tôi cũng đã sửa lỗi cú pháp trong cách sử dụng echo để thoát khỏi các dấu lớn hơn và nhỏ hơn. Ngoài ra, các exitnhu cầu /Btranh luận nếu không CMD.exesẽ bỏ.

@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] == [] tốt hơn "% 1" == "" vì nó sẽ xử lý chính xác trường hợp% 1 chính nó chứa dấu ngoặc kép. "% 1" == "" sẽ bị lỗi với thông báo "không mong muốn tại thời điểm này".
tekumara

2
Lưu ý rằng, nếu bạn không sử dụng đối số dòng lệnh mà là setbiến (tôi không biết thuật ngữ lô chính xác), bạn có thể muốn sử dụng "%myvar%"==""vì nếu myvarcó khoảng trắng trong đó và không được trích dẫn, bạn sẽ nhận được thông báo "không mong muốn tại thời điểm này " thông điệp.
Pat

1
Các biến @Pat SET có thể được kiểm tra bằng IF NOT DEFINED VarNamekhối. Cũng +1 cho tukushan vì không sử dụng dấu ngoặc kép để so sánh. Đừng làm vậy. Không bao giờ.
Fr0sT

10
"%~1"==""cũng sẽ làm việc và chăm sóc các trường hợp% 1 có dấu ngoặc kép
Drakkim

8
"%~1"==""xử lý khoảng trắng trong biến trong khi []phiên bản thì không.
Cookie Butter

17

Một ví dụ nâng cao hơn:

⍟ đối số không giới hạn.

⍟ tồn tại trên hệ thống tệp (hoặc filehoặc directory?) Hoặc chung string.

⍟ chỉ định nếu là một tệp

⍟ chỉ định là một thư mục

không có phần mở rộng, sẽ hoạt động trong các tập lệnh cũ!

mã tối thiểu ☺

@echo tắt

:vòng
      :: -------------------------- có đối số?
      nếu ["% ~ 1"] == [""] (
        echo xong.
        goto end
      )
      :: -------------------------- tồn tại đối số?
      nếu không tồn tại% ~ s1 (
        tiếng vang không tồn tại
      ) else (
        tiếng vang tồn tại
        nếu tồn tại% ~ s1 \ NUL (
          echo là một thư mục
        ) else (
          echo là một tập tin
        )
      )
      :: --------------------------
      sự thay đổi
      vòng lặp goto
      
      
:kết thúc

tạm ngừng

✨ những thứ khác..✨

■ trong %~1- ~loại bỏ bất kỳ gói "hoặc '.

■ in %~s1- the stạo nên đường dẫn DOS 8.3 naming, đó là một mẹo hay để tránh khoảng trắng trong tên tệp khi kiểm tra nội dung (và cách này không cần phải bọc tài nguyên bằng nhiều "s.

["%~1"]==[""]"không thể chắc chắn" nếu đối số là tệp / thư mục hay chỉ là một chuỗi chung chung, vì vậy thay vào đó, biểu thức sử dụng dấu ngoặc và nguyên bản chưa được sửa đổi %1(chỉ cần không có "gói, nếu có ..)

nếu không có đối số nào về việc nếu chúng ta đã sử dụng shiftvà con trỏ arg-list đã vượt qua đối số cuối cùng, biểu thức sẽ được đánh giá thành [""]==[""].

■ điều này càng cụ thể mà bạn có thể thực hiện mà không cần sử dụng thêm thủ thuật (nó sẽ hoạt động ngay cả trong các tập lệnh hàng loạt của windows-95 ...)

■ ví dụ thực thi

lưu nó dưới dạng identifier.cmd

nó có thể xác định các đối số không giới hạn (thông thường bạn bị giới hạn %1- %9), chỉ cần nhớ đặt các đối số bằng dấu phẩy ngược hoặc sử dụng cách đặt tên 8.3 hoặc kéo và thả chúng qua (nó tự động thực hiện một trong hai cách trên).


điều này cho phép bạn chạy các lệnh sau:

identifier.cmd c:\windows và để có được

hiện hữu
là một thư mục
làm xong

identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" và để có được

hiện hữu
là một tập tin
làm xong

⓷ và nhiều đối số (tất nhiên đây là toàn bộ vấn đề ..)

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

và để có được

hiện hữu
là một thư mục
hiện hữu
là một tập tin
hiện hữu
là một tập tin
không tồn tại
làm xong.

tự nhiên nó có thể phức tạp hơn rất nhiều, nhưng các ví dụ đẹp phải luôn đơn giản và tối thiểu. :)

Hy vọng nó sẽ giúp bất cứ ai :)

được xuất bản tại đây: CMD Ninja - Xử lý đối số không giới hạn, xác định nếu tồn tại trong hệ thống tệp, xác định nếu tệp hoặc thư mục

và đây là một ví dụ hoạt động lấy bất kỳ lượng tệp APK nào (ứng dụng Android) và cài đặt chúng trên thiết bị của bạn thông qua bảng điều khiển gỡ lỗi (ADB.exe): Đặt bài viết trước thành trình cài đặt APK hàng loạt không sử dụng cú pháp ADB Install-Multi


14

Bỏ dấu ngoặc đơn.

Tệp lô mẫu:

echo "%1"

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

if "%1"=="" echo match2

Đầu ra từ việc chạy tập lệnh trên:

C:\>echo "" 
""

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

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

Tôi nghĩ rằng nó thực sự là lấy dấu ngoặc đơn là một phần của chuỗi và chúng đang được so sánh.


1
if "%1"==""sẽ sụp đổ nếu đối số có khoảng trắng. Ví dụ: run.bat "a b". @amr có câu trả lời tốt nhất để sử dụngif "%~1"==""
wisbucky

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

~ sẽ bỏ báo giá% 1 nếu chính% 1 được trích dẫn.

"" sẽ bảo vệ khỏi các ký tự đặc biệt được chuyển qua. ví dụ: gọi tập lệnh bằng & ping


1
Đây là câu trả lời tốt nhất. Những câu trả lời khác làm việc cho một số trường hợp, nhưng sẽ thất bại đối với trường hợp đặc biệt hơn nhưrun.bat "a b"
wisbucky

@wisbucky Điều đó dường như không làm rối câu trả lời được chấp nhận . Tôi đang thiếu gì?
ruffin vào

@ruffin, Ví dụ: run.bat ""sẽ không bị bắt bởi với [%1]==[].
khôn ngoan


2

Điều này giống với các câu trả lời khác, nhưng chỉ sử dụng một nhãn và đặt cách sử dụng lên hàng đầu, điều này cũng làm cho nó đóng vai trò như một loại tài liệu khen ngợi về tập lệnh cũng thường được đặt ở trên cùng:

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

Tuy nhiên, nếu bạn không phải sử dụng cmd / batch, hãy sử dụng bash trên WSL hoặc powershell, chúng có cú pháp lành mạnh hơn và ít tính năng phức tạp hơn.


0

NẾU "% 1" == "" sẽ không thành công, tất cả các phiên bản của điều này sẽ không thành công trong các điều kiện ký tự độc nhất định. Chỉ NẾU ĐƯỢC ĐỊNH NGHĨA hoặc NẾU KHÔNG ĐƯỢC ĐỊNH NGHĨA mới an toàn


if [not] defined ...không hoạt động với các tham số như %1. Bạn có một ví dụ, nơi if "%~1" ...không hoạt động?
Stephan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.