Sử dụng tham số trong các tệp bó trong dòng lệnh Windows


161

Trong Windows, làm thế nào để bạn truy cập các đối số được truyền khi tệp bó được chạy?

Ví dụ: giả sử tôi có một chương trình được đặt tên hello.bat. Khi tôi nhập hello -avào một dòng lệnh Windows, làm cách nào để chương trình của tôi biết rằng nó -ađược truyền vào dưới dạng đối số?


Cách truyền tham số dòng lệnh vào tệp bó: stackoverflow.com/questions/26551/
Kẻ

3
Ông đề cập đến "dòng lệnh DOS".
David R Tribble

Câu trả lời:


287

Như những người khác đã nói, các tham số được truyền qua dòng lệnh có thể được truy cập trong các tệp bó với ký hiệu %1%9. Ngoài ra còn có hai mã thông báo khác mà bạn có thể sử dụng:

  • %0tên thực thi (tệp bó) như được chỉ định trong dòng lệnh .
  • %*tất cả các tham số được chỉ định trong dòng lệnh - điều này rất hữu ích nếu bạn muốn chuyển tiếp các tham số sang chương trình khác.

Ngoài ra còn có rất nhiều kỹ thuật quan trọng cần lưu ý ngoài việc đơn giản là làm thế nào để truy cập các tham số.

Kiểm tra nếu một tham số đã được thông qua

Điều này được thực hiện với các cấu trúc như IF "%~1"=="", điều này đúng khi và chỉ khi không có đối số nào được thông qua. Lưu ý ký tự dấu ngã làm cho bất kỳ dấu ngoặc kép nào bị xóa khỏi giá trị của %1; không có dấu ngã, bạn sẽ nhận được kết quả không mong muốn nếu giá trị đó bao gồm dấu ngoặc kép, bao gồm cả khả năng lỗi cú pháp.

Xử lý hơn 9 đối số (hoặc chỉ làm cho cuộc sống dễ dàng hơn)

Nếu bạn cần truy cập nhiều hơn 9 đối số, bạn phải sử dụng lệnh SHIFT. Lệnh này dịch chuyển các giá trị của tất cả các đối số một vị trí, do đó, %0lấy giá trị của %1, %1lấy giá trị của %2, v.v. %9lấy giá trị của đối số thứ mười (nếu có), không có sẵn thông qua bất kỳ biến nào trước khi gọi SHIFT(enter lệnh SHIFT /?cho nhiều tùy chọn hơn).

SHIFTcũng hữu ích khi bạn muốn dễ dàng xử lý các tham số mà không yêu cầu chúng được trình bày theo một thứ tự cụ thể. Ví dụ, một tập lệnh có thể nhận ra các cờ -a-btheo bất kỳ thứ tự nào. Một cách hay để phân tích dòng lệnh trong những trường hợp như vậy là

:parse
IF "%~1"=="" GOTO endparse
IF "%~1"=="-a" REM do something
IF "%~1"=="-b" REM do something else
SHIFT
GOTO parse
:endparse
REM ready for action!

Lược đồ này cho phép bạn phân tích các dòng lệnh khá phức tạp mà không bị điên.

Thay thế các tham số lô

Đối với các tham số thể hiện tên tệp, shell cung cấp nhiều chức năng liên quan đến làm việc với các tệp không thể truy cập theo bất kỳ cách nào khác. Chức năng này được truy cập với các cấu trúc bắt đầu bằng %~.

Ví dụ: để có được kích thước của tệp được truyền vào làm đối số sử dụng

ECHO %~z1

Để có được đường dẫn của thư mục nơi tệp bó được khởi chạy từ (rất hữu ích!) Bạn có thể sử dụng

ECHO %~dp0

Bạn có thể xem toàn bộ phạm vi của các khả năng này bằng cách nhập CALL /?vào dấu nhắc lệnh.


4
Cấu trúc: parse ,: endparse là vẻ đẹp, ngay cả với GOTO. Cảm ơn! (Ý tôi là, GOTO bắt buộc DOS-BASIC)
mmrtnt

1
Kỹ thuật này có thể thất bại khi gọi BAT từ powershell. Một đối số được trích dẫn như "name=John"sẽ trở thành name Johntrong exe. Một cách giải quyết là bao quanh với các trích dẫn đơn,'"name=John"'
cmcginty

1
Làm thế nào tôi đã đi quá lâu mà không có CALL /?!? Ở đây tôi đã va chạm với Google suốt thời gian qua.
bigtlb

@Jon Tôi đã viết tệp bat chỉ chứa một mã echo% 1 nếu tôi gọi nó qua cmd, ví dụ: xx.bat & tham số> "C: \ yy.txt" gọi tệp bat với tham số và ghi vào tệp txt nhưng nếu tôi cho & trong tham số ở đầu hoặc cuối nó không hoạt động. Bất kỳ văn bản khác làm việc tốt.
Alex Mathew

56

Sử dụng tham số trong tệp bó:% 0 và% 9

Các tệp hàng loạt có thể tham chiếu đến các từ được truyền dưới dạng tham số với mã thông báo: %0to %9.

%0 is the program name as it was called.
%1 is the first command line parameter
%2 is the second command line parameter
and so on till %9.

các tham số được truyền vào trong dòng lệnh phải là các ký tự chữ và số và được phân cách bằng dấu cách. Vì %0tên chương trình như đã được gọi, trong DOS %0sẽ trống cho AUTOEXEC.BAT nếu được khởi động khi khởi động.

Thí dụ:

Đặt lệnh sau trong một tệp bó gọi là mybatch.bat:

@echo off
@echo hello %1 %2
pause

Gọi tệp bó như thế này: mybatch john billysẽ xuất ra:

hello john billy

Nhận nhiều hơn 9 tham số cho một tệp bó, sử dụng:% *

Mã thông báo Percent Star %*có nghĩa là "phần còn lại của các tham số". Bạn có thể sử dụng vòng lặp for để lấy chúng, như được định nghĩa ở đây:

http://www.robvanderwoude.com/parameter.php

Lưu ý về dấu phân cách cho tham số lô

Một số ký tự trong tham số dòng lệnh bị bỏ qua bởi các tệp bó, tùy thuộc vào phiên bản DOS, liệu chúng có "thoát" hay không và thường phụ thuộc vào vị trí của chúng trong dòng lệnh:

commas (",") are replaced by spaces, unless they are part of a string in 
double quotes

semicolons (";") are replaced by spaces, unless they are part of a string in 
double quotes

"=" characters are sometimes replaced by spaces, not if they are part of a 
string in double quotes

the first forward slash ("/") is replaced by a space only if it immediately 
follows the command, without a leading space

multiple spaces are replaced by a single space, unless they are part of a 
string in double quotes

tabs are replaced by a single space

leading spaces before the first command line argument are ignored

5

Batch Files tự động chuyển văn bản sau chương trình miễn là chúng là các biến để gán chúng. Chúng được thông qua theo thứ tự chúng được gửi đi; ví dụ% 1 sẽ là chuỗi đầu tiên được gửi sau khi chương trình được gọi, v.v.

Nếu bạn có Hello.bat và nội dung là:

@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause

và bạn gọi lô trong lệnh thông qua

xin chào.bat APerson241% ngày%

bạn sẽ nhận được tin nhắn này trở lại:

Xin chào, APerson241 cảm ơn vì đã chạy tệp bó này (01/11/2013)


4

@ Jon's :parse/ :endparselược đồ là một khởi đầu tuyệt vời và anh ấy có lòng biết ơn của tôi đối với việc vượt qua ban đầu, nhưng nếu bạn nghĩ rằng hệ thống hàng loạt tra tấn Windows sẽ cho phép bạn thoát khỏi điều đó dễ dàng, bạn của tôi, bạn sẽ bị sốc. Tôi đã dành cả ngày với thứ quỷ dữ này, và sau nhiều nghiên cứu và thử nghiệm đau đớn, cuối cùng tôi cũng đã quản lý được thứ gì đó khả thi cho một tiện ích thực tế.

Hãy để chúng tôi nói rằng chúng tôi muốn thực hiện một tiện ích foobar. Nó đòi hỏi một lệnh ban đầu. Nó có một tham số tùy chọn --footrong đó có một giá trị tùy chọn (dĩ nhiên không thể là tham số khác); nếu giá trị bị thiếu, nó mặc định là default. Nó cũng có một tham số tùy chọn --barcần một giá trị bắt buộc . Cuối cùng, nó có thể lấy một lá cờ --bazkhông có giá trị cho phép. Oh, và những thông số này có thể đến theo thứ tự bất kỳ.

Nói cách khác, nó trông như thế này:

foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]

Phức tạp? Không, điều đó có vẻ khá điển hình của các tiện ích trong cuộc sống thực. (có gitai không?)

Nếu không có thêm rắc rối, đây là một giải pháp:

@ECHO OFF
SETLOCAL
REM FooBar parameter demo
REM By Garret Wilson

SET CMD=%~1

IF "%CMD%" == "" (
  GOTO usage
)
SET FOO=
SET DEFAULT_FOO=default
SET BAR=
SET BAZ=

SHIFT
:args
SET PARAM=%~1
SET ARG=%~2
IF "%PARAM%" == "--foo" (
  SHIFT
  IF NOT "%ARG%" == "" (
    IF NOT "%ARG:~0,2%" == "--" (
      SET FOO=%ARG%
      SHIFT
    ) ELSE (
      SET FOO=%DEFAULT_FOO%
    )
  ) ELSE (
    SET FOO=%DEFAULT_FOO%
  )
) ELSE IF "%PARAM%" == "--bar" (
  SHIFT
  IF NOT "%ARG%" == "" (
    SET BAR=%ARG%
    SHIFT
  ) ELSE (
    ECHO Missing bar value. 1>&2
    ECHO:
    GOTO usage
  )
) ELSE IF "%PARAM%" == "--baz" (
  SHIFT
  SET BAZ=true
) ELSE IF "%PARAM%" == "" (
  GOTO endargs
) ELSE (
  ECHO Unrecognized option %1. 1>&2
  ECHO:
  GOTO usage
)
GOTO args
:endargs

ECHO Command: %CMD%
IF NOT "%FOO%" == "" (
  ECHO Foo: %FOO%
)
IF NOT "%BAR%" == "" (
  ECHO Bar: %BAR%
)
IF "%BAZ%" == "true" (
  ECHO Baz
)

REM TODO do something with FOO, BAR, and/or BAZ
GOTO :eof

:usage
ECHO FooBar
ECHO Usage: foobar ^<command^> [--foo [^<fooval^>]] [--bar ^<barval^>] [--baz]
EXIT /B 1

Vâng, nó thực sự là xấu. Xem bài đăng tương tự của tôi tại https://stackoverflow.com/a/50653047/421049 , nơi tôi cung cấp thêm phân tích về những gì đang diễn ra trong logic và tại sao tôi sử dụng một số cấu trúc nhất định.

Thật gớm ghiếc. Hầu hết điều đó tôi đã phải học ngày hôm nay. Và nó đau.


3

Sử dụng các biến tức là .BATbiến và gọi %0đến%9

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.