Menggunakan parameter dalam file batch di baris perintah Windows

161

Di Windows, bagaimana Anda mengakses argumen yang dilewati ketika file batch dijalankan?

Sebagai contoh, katakanlah saya memiliki program bernama hello.bat. Ketika saya masuk hello -apada baris perintah Windows, bagaimana saya membiarkan program saya tahu bahwa -aitu dilewatkan sebagai argumen?

Seseorang
sumber
Cara meneruskan parameter baris perintah ke file batch: stackoverflow.com/questions/26551/…
Eric Leschinski
3
Dia menyebutkan "baris perintah DOS".
David R Tribble

Jawaban:

287

Seperti yang telah dikatakan orang lain, parameter yang melewati baris perintah dapat diakses dalam file batch dengan notasi %1ke %9. Ada juga dua token lain yang dapat Anda gunakan:

  • %0adalah nama (file file) yang dapat dieksekusi sebagaimana ditentukan dalam baris perintah .
  • %*adalah semua parameter yang ditentukan dalam baris perintah - ini sangat berguna jika Anda ingin meneruskan parameter ke program lain.

Ada juga banyak teknik penting yang harus diperhatikan selain hanya cara mengakses parameter.

Memeriksa apakah suatu parameter telah dilewati

Ini dilakukan dengan konstruksi seperti IF "%~1"=="", yang benar jika dan hanya jika tidak ada argumen yang disahkan sama sekali. Perhatikan karakter tilde yang menyebabkan tanda kutip sekitarnya dihapus dari nilai %1; tanpa tilde, Anda akan mendapatkan hasil yang tidak terduga jika nilai tersebut mencakup tanda kutip ganda, termasuk kemungkinan kesalahan sintaksis.

Menangani lebih dari 9 argumen (atau hanya membuat hidup lebih mudah)

Jika Anda perlu mengakses lebih dari 9 argumen, Anda harus menggunakan perintah SHIFT. Perintah ini menggeser nilai semua argumen satu tempat, sehingga %0mengambil nilai %1, %1mengambil nilai %2, dll. %9Mengambil nilai argumen kesepuluh (jika ada), yang tidak tersedia melalui variabel apa pun sebelum memanggil SHIFT(masukkan perintah SHIFT /?untuk lebih banyak opsi).

SHIFTjuga berguna ketika Anda ingin dengan mudah memproses parameter tanpa mengharuskan mereka disajikan dalam urutan tertentu. Misalnya, skrip dapat mengenali bendera -adan -bdalam urutan apa pun. Cara yang baik untuk mengurai baris perintah dalam kasus seperti ini adalah

: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!

Skema ini memungkinkan Anda untuk mengurai baris perintah yang cukup rumit tanpa menjadi gila.

Substitusi parameter batch

Untuk parameter yang mewakili nama file, shell menyediakan banyak fungsi yang terkait dengan bekerja dengan file yang tidak dapat diakses dengan cara lain. Fungsi ini diakses dengan konstruk yang dimulai dengan %~.

Misalnya, untuk mendapatkan ukuran file yang diteruskan sebagai argumen gunakan

ECHO %~z1

Untuk mendapatkan jalur direktori tempat file batch diluncurkan (sangat berguna!) Dapat Anda gunakan

ECHO %~dp0

Anda dapat melihat berbagai kemampuan ini dengan mengetikkan CALL /?prompt perintah.

Jon
sumber
4
Konstruksi: parse,: endparse adalah keindahan, bahkan dengan GOTO. Terima kasih! (Maksud saya, DOS-BASIC memaksa GOTO)
mmrtnt
1
Teknik ini mungkin gagal saat memanggil BAT dari PowerShell. Argumen yang dikutip seperti "name=John"akan menjadi name Johnselama exe. Solusinya adalah dengan mengelilingi dengan tanda kutip tunggal,'"name=John"'
cmcginty
1
Bagaimana saya bisa begitu lama tanpanya CALL /?!? Di sini saya telah bertabrakan dengan Google sepanjang waktu.
bigtlb
@Jon saya menulis file bat yang hanya berisi satu kode gema% 1 jika saya menyebutnya melalui cmd misalnya xx.bat & parameter> "C: \ yy.txt" memanggil file bat dengan parameter dan menulis ke file txt tetapi jika saya memberi & dalam parameter di awal atau akhir itu tidak berfungsi. Teks lain berfungsi dengan baik.
Alex Mathew
56

Menggunakan parameter dalam file batch:% 0 dan% 9

File batch dapat merujuk pada kata-kata yang dikirimkan sebagai parameter dengan token: %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.

parameter yang diteruskan pada commandline harus berupa karakter alfanumerik dan dibatasi oleh spasi. Karena %0ini adalah nama program seperti yang dipanggil, dalam DOS %0akan kosong untuk AUTOEXEC.BAT jika dimulai saat boot.

Contoh:

Masukkan perintah berikut dalam file batch yang disebut mybatch.bat:

@echo off
@echo hello %1 %2
pause

Meminta file batch seperti ini: mybatch john billyakan menampilkan:

hello john billy

Dapatkan lebih dari 9 parameter untuk file batch, gunakan:% *

Token Bintang Persen %*berarti "sisa parameter". Anda bisa menggunakan for for untuk mengambilnya, seperti yang didefinisikan di sini:

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

Catatan tentang pembatas untuk parameter batch

Beberapa karakter dalam parameter baris perintah diabaikan oleh file batch, tergantung pada versi DOS, apakah mereka "lolos" atau tidak, dan sering kali tergantung pada lokasi mereka di baris perintah:

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
Eric Leschinski
sumber
5

File Batch secara otomatis mengirimkan teks setelah program selama variabel-variabelnya adalah untuk ditugaskan. Mereka lulus agar mereka dikirim; misal% 1 akan menjadi string pertama yang dikirim setelah program dipanggil, dll.

Jika Anda memiliki Hello.bat dan isinya adalah:

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

dan Anda memanggil batch dalam perintah via

hello.bat APerson241% tanggal%

Anda harus menerima pesan ini kembali:

Halo, APerson241 terima kasih telah menjalankan file batch ini (01/11/2013)

rud3y
sumber
4

@ Jon :parse/ :endparseskema adalah awal yang baik, dan dia memiliki rasa syukur saya untuk lulus awal, tetapi jika Anda berpikir bahwa sistem Windows menyiksa batch yang akan membiarkan Anda pergi mudah ... dengan baik, teman saya, Anda berada dalam untuk shock. Saya telah menghabiskan sepanjang hari dengan iblis ini, dan setelah banyak penelitian dan percobaan yang menyakitkan akhirnya saya berhasil sesuatu yang berguna untuk utilitas kehidupan nyata.

Mari kita katakan bahwa kita ingin mengimplementasikan suatu utilitas foobar. Itu membutuhkan perintah awal. Ini memiliki parameter opsional --fooyang mengambil nilai opsional (yang tidak bisa menjadi parameter lain, tentu saja); jika nilai tidak ada, defaultnya adalah default. Ini juga memiliki parameter opsional --baryang mengambil nilai yang diperlukan . Terakhir dapat mengambil bendera --baztanpa nilai yang diizinkan. Oh, dan parameter ini bisa datang dalam urutan apa pun.

Dengan kata lain, tampilannya seperti ini:

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

Rumit? Tidak, itu kelihatannya tipikal utilitas kehidupan nyata. ( gitsiapa pun?)

Tanpa basa-basi lagi, berikut adalah solusinya:

@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

Ya, itu seburuk itu. Lihat posting saya yang serupa di https://stackoverflow.com/a/50653047/421049 , di mana saya memberikan lebih banyak analisis tentang apa yang terjadi dalam logika, dan mengapa saya menggunakan konstruksi tertentu.

Mengerikan. Sebagian besar dari itu harus saya pelajari hari ini. Dan itu menyakitkan.

Garret Wilson
sumber
3

Gunakan variabel yaitu .BATvariabel dan dipanggil %0ke%9

tohava
sumber