Làm thế nào tôi có thể truyền đối số cho một tệp bó?


1167

Tôi cần chuyển ID và mật khẩu cho một tệp bó tại thời điểm chạy thay vì mã hóa chúng vào tệp.

Đây là dòng lệnh trông như thế nào:

test.cmd admin P@55w0rd > test-log.txt

8
Đối với "tất cả phần còn lại", hãy xem nhận xét của Greg Hegill tại cách nhận thông số tệp bó từ vị trí thứ N trên?
matt wilkie

Tôi có một tập lệnh khởi động môi trường sẽ đẩy tên người dùng / mật khẩu của tôi vào các biến môi trường ... để tôi không phải gõ chúng mỗi lần ... Tôi sử dụng bash hầu hết thời gian (linux, mac và windows) và cần sử dụng nó cho các cấu hình proxy trong các tập lệnh, vv cho công việc.
Tracker1

Câu trả lời:


1032

Một mẹo hữu ích khác là sử dụng %*để chỉ "tất cả". Ví dụ:

echo off
set arg1=%1
set arg2=%2
shift
shift
fake-command /u %arg1% /p %arg2% %*

Khi bạn chạy:

test-command admin password foo bar

tệp bó trên sẽ chạy:

fake-command /u admin /p password admin password foo bar

Tôi có thể có cú pháp hơi sai, nhưng đây là ý tưởng chung.


123
% * thực sự mở rộng cho tất cả các tham số bất kể sự thay đổi. Vì vậy, ngay cả sau hai ca, bạn vẫn sẽ có hai đối số đầu tiên trong% *. Bạn có thể sử dụng một cái gì đó như thế này: stackoverflow.com/questions/761615/ từ để lấy một biến chứa mọi thứ trừ n tham số đầu tiên.
Joey

1
Xin lưu ý rằng% * không hoạt động ở mọi nơi! Chẳng hạn, nó không hoạt động với DOSBox 0.73 (có thể đây là một lỗi cần được báo cáo).
Denilson Sá Maia

28
Đây không phải là lỗi vì% * không bao giờ hoạt động trong MS-DOS hoặc Win9x ngay từ đầu.
Kef Schecter

Tôi nghĩ rằng shift"bật" đối số từ danh sách. Giả định của OP là %*sẽ chỉ đưa ra các đối số còn lại, nhưng nó không hoạt động theo cách đó, như @Joey nói.
NathanAldenSr

5
Câu trả lời này là sai. Nó thực sự dẫn đến kết quả fake-command /u admin /p password admin password foo bar. Điều này đã được @Joey chỉ ra từ nhiều năm trước.
jwdonahue

286

Đây là cách tôi đã làm:

@fake-command /u %1 /p %2

Đây là những gì lệnh trông giống như:

test.cmd admin P@55w0rd > test-log.txt

Áp %1dụng cho tham số đầu tiên %2(và đây là phần khó khăn) áp dụng cho tham số thứ hai. Bạn có thể có tối đa 9 tham số được truyền theo cách này.


16
Nếu bạn ngu ngốc như tôi, tâm trí của bạn đang tìm kiếm echo %1 %2và bị loại bỏ bởi trường hợp đơn giản nhất không bị cắt xén với a @và a fake-commandvới thông số, nghĩ rằng chúng ta sẽ nhận được fake-command.batnội dung sau này (trong trường hợp đó, quá phức tạp fake-command.batcó thể phải echo %2 %4bỏ qua các tên param). Sai, doofus. TL; DR: Đừng ngu ngốc như tôi. 1. echo echo %1 %2 > test.bat2 test word1 word2.. 3. Lợi nhuận.
ruffin

143

Nếu bạn muốn xử lý thông minh các tham số bị thiếu một cách thông minh, bạn có thể thực hiện một số việc như:

IF %1.==. GOTO No1
IF %2.==. GOTO No2
... do stuff...
GOTO End1

:No1
  ECHO No param 1
GOTO End1
:No2
  ECHO No param 2
GOTO End1

:End1

2
Tầm quan trọng của dấu chấm / thời gian trong các hoạt động bình đẳng này là gì?
Chris

4
Về cơ bản nếu% 1 trống, điều này sẽ trở thành IF. ==. và vì vậy GOTO sẽ xảy ra. Chúng tôi sử dụng x ở đây vì vậy: IF x% 1 == x -> IF x == x -> true
Carl

1
Bạn nên biết giá trị của "đối số không được cung cấp" là gì? Xác nhận những gì bạn nên kiểm tra một "đối số không được cung cấp"? Sau đó, nếu bạn không có câu trả lời, bạn nên sử dụng một mẹo như một trong những dấu chấm. Hãy nhớ rằng, như đã nêu ở đây ss64.com/nt/if.html "Thực tế bạn có thể sử dụng hầu hết mọi ký tự cho dấu '~' hoặc dấu ngoặc nhọn, {} hoặc thậm chí là số 4, nhưng dấu ngoặc vuông có xu hướng được chọn vì chúng không có ý nghĩa đặc biệt nào. "
Adriano GV Esposito

89

Truy cập các tham số lô có thể đơn giản với% 1,% 2, ...% 9 hoặc cũng% *,
nhưng chỉ khi nội dung đơn giản.

Không có cách đơn giản nào cho các nội dung phức tạp như "&"^&, vì không thể truy cập% 1 mà không gây ra lỗi.

set  var=%1
set "var=%1"
set  var=%~1
set "var=%~1"

Các dòng mở rộng đến

set  var="&"&
set "var="&"&"
set  var="&"&
set "var="&"&"

Và mỗi dòng đều thất bại, vì một trong những điều &nằm ngoài dấu ngoặc kép.

Nó có thể được giải quyết bằng cách đọc từ một tệp tạm thời một phiên bản được chú ý của tham số.

@echo off
SETLOCAL DisableDelayedExpansion

SETLOCAL
for %%a in (1) do (
    set "prompt="
    echo on
    for %%b in (1) do rem * #%1#
    @echo off
) > param.txt
ENDLOCAL

for /F "delims=" %%L in (param.txt) do (
  set "param1=%%L"
)
SETLOCAL EnableDelayedExpansion
set "param1=!param1:*#=!"
set "param1=!param1:~0,-2!"
echo %%1 is '!param1!'

Thủ thuật là kích hoạt echo onvà mở rộng% 1 sau một remcâu lệnh (cũng hoạt động với %2 .. %*).
Vì vậy, thậm chí "&"&có thể được lặp lại mà không tạo ra một lỗi, vì nó được nhận xét.

Nhưng để có thể chuyển hướng đầu ra của echo on, bạn cần hai vòng lặp for.

Các ký tự phụ * #được sử dụng để an toàn đối với các nội dung như /?(sẽ hiển thị trợ giúp cho REM).
Hoặc một dấu mũ ^ ở cuối dòng có thể hoạt động như một nhân vật đa dòng, ngay cả sau một rem.

Sau đó đọc đầu ra tham số rem từ tệp, nhưng cẩn thận.
FOR / F sẽ hoạt động với việc mở rộng bị trì hoãn, các nội dung khác có "!" sẽ bị phá hủy
Sau khi loại bỏ các ký tự phụ param1, bạn đã nhận được nó.

Và để sử dụng param1một cách an toàn, cho phép mở rộng bị trì hoãn.


for / F "tokens = *" %% a in ('echo% *') được đặt "all_args = %% a"
Kevin Edwards

@KevinEdwards Sau đó, hãy thử với một &, giải pháp của bạn chỉ hoạt động với nội dung đơn giản
jeb

@KevinEdwards Tôi đã thử nó, test.bat ^&và nó thất bại. Chỉ test.bat "&"hoạt động, nhưng đó không phải là quan điểm của tôi. Bạn không thể sử dụng %*, %1một cách an toàn mà không cần kỹ thuật REM
jeb

À, vâng, một dấu mũ không thoát khỏi nó đúng cách. Bạn cần báo giá, khả thi cho tất cả các trường hợp sử dụng mà tôi đã gặp. Tôi chỉ muốn vượt qua nó cùng. Cảm ơn đã thử nghiệm nó! Chúc mừng :)
Kevin Edwards

2
@jwdonahue Vâng, nó phức tạp (nhưng không quá phức tạp). Nhưng đặc biệt là cho các mật khẩu đó có thể là cần thiết, ít nhất là một số mật khẩu của tôi chứa ampersands &và cũng trích dẫn"
Jeb

59

Đúng, và đừng quên sử dụng các biến như %%1khi sử dụng ifforbăng đảng.

Nếu bạn quên gấp đôi %, thì bạn sẽ thay thế trong các đối số dòng lệnh (có thể là null) và bạn sẽ nhận được một số thông báo lỗi khá khó hiểu.


%% chỉ dành cho iffor?
Royi Namir

25
Tệ hơn thế - %% được sử dụng cho các biến tiền tố và tham số dòng lệnh bên trong các tệp bó. Nhưng khi bạn sử dụng các lệnh này từ dòng lệnh, bạn chỉ sử dụng% để tiền tố. Ví dụ: bên trong lô: for %%d in (*) do echo %%dtừ dòng lệnh:for %d in (*) do echo %d
Steve Midgley

11
@SteveUngley Tôi đã đưa ra nhận xét của bạn có lẽ cách đây một năm. Sau đó tôi nhanh chóng quên nó và chỉ hôm nay tôi đang cố gắng và nhìn chằm chằm vào vòng lặp for của tôi trong dòng lệnh và tự hỏi tại sao nó lại xì hơi và không làm gì khác. Vì vậy, đây là một upvote ảo khác từ tôi. Tôi sẽ trở lại sau một năm nữa khi tôi gặp lại vấn đề tương tự.
icc97

Chúng tôi thường dành các chữ số để xử lý dòng lệnh và phần trăm kép chỉ áp dụng cho câu lệnh for theo như tôi biết. @for %%2 in (testing) do @echo %%2 %1trong một tệp bó, tạo ra testing 1khi nó được gọi với 1 ( test 1).
jwdonahue

2
Câu trả lời là sai. %%1không truy cập một đối số dòng lệnh và nó cũng sai cho IFlệnh. Chỉ FORlệnh (trong tệp bó) yêu cầu hai phần trăm, nhưng ngay cả khi đó %%1sẽ xác định tham số FOR và không truy cập đối số
jeb

51

Không cần phải phức tạp hóa nó. Nó chỉ đơn giản là lệnh% 1% 2 tham số, ví dụ,

@echo off

xcopy %1 %2 /D /E /C /Q /H /R /K /Y /Z

echo copied %1 to %2

pause

"Tạm dừng" hiển thị những gì tệp bó đã thực hiện và chờ bạn nhấn phím BẤT K .. Lưu nó dưới dạng xx.bat trong thư mục Windows.

Để sử dụng nó, hãy nhập, ví dụ:

xx c:\f\30\*.* f:\sites\30

Tệp bó này chăm sóc tất cả các tham số cần thiết, như chỉ sao chép các tệp mới hơn, v.v. Tôi đã sử dụng nó từ trước Windows. Nếu bạn muốn xem tên của các tệp, vì chúng đang được sao chép, hãy bỏ qua Qtham số.


41

Một người bạn đã hỏi tôi về chủ đề này gần đây, vì vậy tôi nghĩ rằng tôi đã đăng cách tôi xử lý các đối số dòng lệnh trong các tệp bó.

Kỹ thuật này có một chút chi phí như bạn sẽ thấy, nhưng nó làm cho các tệp bó của tôi rất dễ hiểu và nhanh chóng thực hiện. Cũng như hỗ trợ các cấu trúc sau:

>template.bat [-f] [--flag] [/f] [--namedvalue value] arg1 [arg2][arg3][...]

Các jist của nó là có :init, :parse:maincác chức năng.

Ví dụ sử dụng

>template.bat /?
test v1.23
This is a sample batch file template,
providing command-line arguments and flags.

USAGE:
test.bat [flags] "required argument" "optional argument"

/?, --help           shows this help
/v, --version        shows the version
/e, --verbose        shows detailed output
-f, --flag value     specifies a named parameter value

>template.bat          <- throws missing argument error
(same as /?, plus..)
****                                   ****
****    MISSING "REQUIRED ARGUMENT"    ****
****                                   ****

>template.bat -v
1.23

>template.bat --version
test v1.23
This is a sample batch file template,
providing command-line arguments and flags.

>template.bat -e arg1
**** DEBUG IS ON
UnNamedArgument:    "arg1"
UnNamedOptionalArg: not provided
NamedFlag:          not provided

>template.bat --flag "my flag" arg1 arg2
UnNamedArgument:    "arg1"
UnNamedOptionalArg: "arg2"
NamedFlag:          "my flag"

>template.bat --verbose "argument #1" --flag "my flag" second
**** DEBUG IS ON
UnNamedArgument:    "argument #1"
UnNamedOptionalArg: "second"
NamedFlag:          "my flag"

template.bat

@::!/dos/rocks
@echo off
goto :init

:header
    echo %__NAME% v%__VERSION%
    echo This is a sample batch file template,
    echo providing command-line arguments and flags.
    echo.
    goto :eof

:usage
    echo USAGE:
    echo   %__BAT_NAME% [flags] "required argument" "optional argument" 
    echo.
    echo.  /?, --help           shows this help
    echo.  /v, --version        shows the version
    echo.  /e, --verbose        shows detailed output
    echo.  -f, --flag value     specifies a named parameter value
    goto :eof

:version
    if "%~1"=="full" call :header & goto :eof
    echo %__VERSION%
    goto :eof

:missing_argument
    call :header
    call :usage
    echo.
    echo ****                                   ****
    echo ****    MISSING "REQUIRED ARGUMENT"    ****
    echo ****                                   ****
    echo.
    goto :eof

:init
    set "__NAME=%~n0"
    set "__VERSION=1.23"
    set "__YEAR=2017"

    set "__BAT_FILE=%~0"
    set "__BAT_PATH=%~dp0"
    set "__BAT_NAME=%~nx0"

    set "OptHelp="
    set "OptVersion="
    set "OptVerbose="

    set "UnNamedArgument="
    set "UnNamedOptionalArg="
    set "NamedFlag="

:parse
    if "%~1"=="" goto :validate

    if /i "%~1"=="/?"         call :header & call :usage "%~2" & goto :end
    if /i "%~1"=="-?"         call :header & call :usage "%~2" & goto :end
    if /i "%~1"=="--help"     call :header & call :usage "%~2" & goto :end

    if /i "%~1"=="/v"         call :version      & goto :end
    if /i "%~1"=="-v"         call :version      & goto :end
    if /i "%~1"=="--version"  call :version full & goto :end

    if /i "%~1"=="/e"         set "OptVerbose=yes"  & shift & goto :parse
    if /i "%~1"=="-e"         set "OptVerbose=yes"  & shift & goto :parse
    if /i "%~1"=="--verbose"  set "OptVerbose=yes"  & shift & goto :parse

    if /i "%~1"=="--flag"     set "NamedFlag=%~2"   & shift & shift & goto :parse

    if not defined UnNamedArgument     set "UnNamedArgument=%~1"     & shift & goto :parse
    if not defined UnNamedOptionalArg  set "UnNamedOptionalArg=%~1"  & shift & goto :parse

    shift
    goto :parse

:validate
    if not defined UnNamedArgument call :missing_argument & goto :end

:main
    if defined OptVerbose (
        echo **** DEBUG IS ON
    )

    echo UnNamedArgument:    "%UnNamedArgument%"

    if defined UnNamedOptionalArg      echo UnNamedOptionalArg: "%UnNamedOptionalArg%"
    if not defined UnNamedOptionalArg  echo UnNamedOptionalArg: not provided

    if defined NamedFlag               echo NamedFlag:          "%NamedFlag%"
    if not defined NamedFlag           echo NamedFlag:          not provided

:end
    call :cleanup
    exit /B

:cleanup
    REM The cleanup function is only really necessary if you
    REM are _not_ using SETLOCAL.
    set "__NAME="
    set "__VERSION="
    set "__YEAR="

    set "__BAT_FILE="
    set "__BAT_PATH="
    set "__BAT_NAME="

    set "OptHelp="
    set "OptVersion="
    set "OptVerbose="

    set "UnNamedArgument="
    set "UnNamedArgument2="
    set "NamedFlag="

    goto :eof

32
@ECHO OFF
:Loop
IF "%1"=="" GOTO Continue
SHIFT
GOTO Loop
:Continue

Lưu ý: IF "%1"==""sẽ gây ra vấn đề nếu %1được đặt trong dấu ngoặc kép.

Trong trường hợp đó, chỉ sử dụng IF [%1]==[]hoặc, trong NT 4 (SP6) và sau đó, IF "%~1"==""thay vào đó.


Đúng như vậy, nhưng nó hầu như không chạm vào vấn đề.
jwdonahue

22

Hãy giữ nó đơn giản.

Đây là tập tin .cmd.

@echo off
rem this file is named echo_3params.cmd
echo %1
echo %2
echo %3
set v1=%1
set v2=%2
set v3=%3
echo v1 equals %v1%
echo v2 equals %v2%
echo v3 equals %v3%

Dưới đây là 3 cuộc gọi từ dòng lệnh.

C:\Users\joeco>echo_3params 1abc 2 def  3 ghi
1abc
2
def
v1 equals 1abc
v2 equals 2
v3 equals def

C:\Users\joeco>echo_3params 1abc "2 def"  "3 ghi"
1abc
"2 def"
"3 ghi"
v1 equals 1abc
v2 equals "2 def"
v3 equals "3 ghi"

C:\Users\joeco>echo_3params 1abc '2 def'  "3 ghi"
1abc
'2
def'
v1 equals 1abc
v2 equals '2
v3 equals def'

C:\Users\joeco>

20
FOR %%A IN (%*) DO (
    REM Now your batch file handles %%A instead of %1
    REM No need to use SHIFT anymore.
    ECHO %%A
)

Vòng lặp này trên các tham số lô (% *) hoặc chúng được trích dẫn hoặc không, sau đó lặp lại từng tham số.


Nhưng không thành công với nhiều lý lẽ khác nhau, như test.bat *.txt, test.bat cat^&doghoặcTest.bat /?
Jeb

19

Tôi đã viết một tập lệnh read_params đơn giản có thể được gọi là một hàm (hoặc bên ngoài .bat) và sẽ đặt tất cả các biến vào môi trường hiện tại. Nó sẽ không sửa đổi các tham số ban đầu vì chức năng đang được chỉnh sửa callvới một bản sao của các tham số ban đầu.

Ví dụ, đưa ra lệnh sau:

myscript.bat some -random=43 extra -greeting="hello world" fluff

myscript.bat sẽ có thể sử dụng các biến sau khi gọi hàm:

call :read_params %*

echo %random%
echo %greeting%

Đây là chức năng:

:read_params
if not %1/==/ (
    if not "%__var%"=="" (
        if not "%__var:~0,1%"=="-" (
            endlocal
            goto read_params
        )
        endlocal & set %__var:~1%=%~1
    ) else (
        setlocal & set __var=%~1
    )
    shift
    goto read_params
)
exit /B

Hạn chế

  • Không thể tải đối số không có giá trị như -force. Bạn có thể sử dụng -force=truenhưng tôi không thể nghĩ ra cách cho phép các giá trị trống mà không biết danh sách các tham số trước thời hạn sẽ không có giá trị.

Thay đổi

  • 18/2/2016
    • Không còn yêu cầu mở rộng chậm trễ
    • Bây giờ làm việc với các đối số dòng lệnh khác bằng cách tìm kiếm -trước các tham số.

Đã xem xét bằng cách sử dụng phương pháp này vì tôi muốn chuyển các đối số vào một tệp bó theo cách này. Tuy nhiên, tôi nhận thấy rằng sau khi các biến được đặt, ngay cả khi thoát tệp bó, các tham số vẫn được đặt trong cmd nếu được truy cập và lô đã kết thúc, chúng không được khôi phục về trạng thái trước đó. Phương pháp này có nên xử lý tình huống đó?
Jono_2007

Về chủ đề và tốt hơn so với một số câu trả lời còn lại về chủ đề này.
jwdonahue

Mở rộng nó để hỗ trợ cờ args (không có giá trị). Xin lỗi vì thiếu định dạng nhưng nó không hoạt động trong các bình luận: read_params nếu không% 1 / == / (nếu không "% __ var%" == "" (nếu không "% __ var: ~ 0,1%" == "-" (endlocal goto read_params) endlocal & set% __ var: ~ 1% =% ~ 1) other (setlocal & set __var =% ~ 1) shift goto read_params) khác (nếu không phải là "% __ var%" == " (endlocal & đặt% __ var: ~ 1% = 1))
Tối đa

13

Trong tập tin lô

set argument1=%1
set argument2=%2
echo %argument1%
echo %argument2%

% 1 và% 2 trả về giá trị đối số thứ nhất và thứ hai tương ứng.

Và trong dòng lệnh, vượt qua các đối số

Directory> batchFileName admin P@55w0rd 

Đầu ra sẽ là

admin
P@55w0rd

9

Để tham khảo một biến được thiết lập trong dòng lệnh, bạn sẽ cần sử dụng %a%, ví dụ:

set a=100 
echo %a%  
rem output = 100 

Lưu ý: Điều này hoạt động cho Windows 7 pro.


6

Lấy cảm hứng từ một câu trả lời ở nơi khác bởi @Jon, tôi đã tạo ra một thuật toán tổng quát hơn để trích xuất các tham số, giá trị tùy chọn và công tắc được đặt tên.

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]

Đâ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
  • Sử dụng SETLOCALđể các biến không thoát vào môi trường gọi.
  • Đừng quên khởi tạo các biến SET FOO=, v.v. trong trường hợp ai đó xác định chúng trong môi trường gọi.
  • Sử dụng %~1để loại bỏ dấu ngoặc kép.
  • Sử dụng IF "%ARG%" == ""và không phải IF [%ARG%] == []bởi vì []không chơi sẽ hoàn toàn có giá trị kết thúc trong một khoảng trắng.
  • Ngay cả khi bạn SHIFTở trong một IFkhối, các đối số hiện tại như %~1không được cập nhật vì chúng được xác định khi IFphân tích cú pháp. Bạn có thể sử dụng %~1%~2bên trong IFkhối, nhưng nó sẽ gây nhầm lẫn bởi vì bạn có một SHIFT. Bạn có thể đặt phần SHIFTcuối của khối cho rõ ràng, nhưng điều đó có thể bị mất và / hoặc gây nhầm lẫn cho mọi người. Vì vậy, "chụp" %~1%~1bên ngoài khối có vẻ tốt nhất.
  • Bạn không muốn sử dụng một tham số thay cho giá trị tùy chọn của tham số khác, vì vậy bạn phải kiểm tra IF NOT "%ARG:~0,2%" == "--".
  • Chỉ cẩn thận SHIFTkhi bạn sử dụng một trong các tham số.
  • Mã trùng lặp SET FOO=%DEFAULT_FOO%là đáng tiếc, nhưng thay thế sẽ là thêm một khối IF "%FOO%" == "" SET FOO=%DEFAULT_FOO%bên ngoài IF NOT "%ARG%" == "". Tuy nhiên vì đây vẫn là bên trong IF "%PARAM%" == "--foo"khối, các %FOO%giá trị sẽ được đánh giá và thiết lập trước khi bạn bước vào khối, vì vậy bạn sẽ không bao giờ phát hiện rằng cả các --footham số đã có mặt và cũng%FOO%giá trị đã mất tích.
  • Lưu ý rằng ECHO Missing bar value. 1>&2gửi thông báo lỗi đến stderr.
  • Muốn có một dòng trống trong tệp bó Windows? Bạn phải sử dụng ECHO:hoặc một trong các biến thể.

4

Tạo một tệp bó mới (ví dụ: openclass.bat) và viết dòng này vào tệp:

java %~n1

Sau đó đặt tệp bó vào, giả sử, thư mục system32, chuyển đến tệp lớp Java của bạn, nhấp chuột phải, Thuộc tính, Mở bằng ..., sau đó tìm tệp bó của bạn, chọn tệp đó và ...

Nó làm việc cho tôi.

Tái bút: Tôi không thể tìm cách đóng cửa sổ cmd khi đóng lớp Java. Bây giờ ...


Bạn có thể đóng cửa sổ cmd sau khi quá trình đã đóng bằng lệnh sau trong tập lệnh bó:start /wait java %~n1
Paint_Ninja

1
Tư vấn cho công chúng để đặt các tập lệnh ngẫu nhiên trong thư mục system32 là vô trách nhiệm. Câu trả lời này thực sự không làm trầy xước bề mặt của chủ đề của chủ đề này.
jwdonahue

2

Giải pháp đơn giản (mặc dù câu hỏi đã cũ)

Test1.bat

echo off
echo "Batch started"
set arg1=%1
echo "arg1 is %arg1%"
echo on
pause

CallTest1.bat

call "C:\Temp\Test1.bat" pass123

đầu ra

YourLocalPath>call "C:\Temp\test.bat" pass123

YourLocalPath>echo off
"Batch started"
"arg1 is pass123"

YourLocalPath>pause
Press any key to continue . . .

Trong đó YourLocalPath là đường dẫn thư mục hiện tại.

Để giữ cho mọi thứ đơn giản lưu trữ lệnh param trong biến và sử dụng biến để so sánh.

Nó không chỉ đơn giản để viết mà còn đơn giản để duy trì vì vậy nếu sau này một người khác hoặc bạn đọc kịch bản của bạn sau một thời gian dài, nó sẽ dễ hiểu và duy trì.

Để viết mã nội tuyến: xem các câu trả lời khác.


2

nhập mô tả hình ảnh ở đây

Để sử dụng looping, hãy lấy tất cả các đối số và theo lô thuần túy:

Quan sát: Để sử dụng mà không có:?*&<>


@echo off && setlocal EnableDelayedExpansion

 for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && (
     call set "_arg_[!_cnt!]=!_arg_!" && for /l %%l in (!_cnt! 1 !_cnt!
     )do echo/ The argument n:%%l is: !_arg_[%%l]!
 )

goto :eof 

Mã của bạn đã sẵn sàng để làm một cái gì đó với số đối số mà nó cần, như ...

 @echo off && setlocal EnableDelayedExpansion

 for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && call set "_arg_[!_cnt!]=!_arg_!"
 )

 fake-command /u !_arg_[1]! /p !_arg_[2]! > test-log.txt

1
Nhưng nó không thành công, khi mật khẩu chứa bất kỳ ký tự nào của?*&<>
jeb

@jeb Cảm ơn bạn một lần nữa, tôi đã thêm ghi chú obs.: để trả lời cho đến khi chỉnh sửa mới để xử lý các nhân vật này ...
Không phải là tôi
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.