Gaya opsi baris perintah - POSIX atau apa?

16

Di suatu tempat saya melihat kata-kata kasar terhadap java / javac diduga menggunakan campuran Windows dan gaya Unix seperti

java -classpath ... -ea ... Something

IMHO, itu bukan campuran, itu seperti findberfungsi juga, bukan? AFAIK, menurut POSIX, sintaks seharusnya seperti

java --classpath ... --ea ... Something

dan -abcdefakan berarti menentukan 6 opsi pendek sekaligus. Saya bertanya-tanya versi mana yang secara umum menyebabkan lebih sedikit pengetikan dan kesalahan.

Saya sedang menulis sebuah utilitas kecil di Jawa dan tidak akan menggunakan gaya Windows /a /bkarena saya tertarik terutama pada Unix. Gaya apa yang harus saya pilih?

maaartinus
sumber
1
POSIX 1003.1-2003, Definisi Dasar, Bab 12, Bagian 2 memberikan pedoman berikut tentang sintaks baris perintah utilitas: "Setiap nama opsi harus berupa karakter alfanumerik tunggal (klasifikasi karakter alnum) dari set karakter portabel." dan "Semua opsi harus didahului oleh karakter pembatas '-'."
Greg A. Woods

Jawaban:

21

Anda dapat menemukan konvensi argumen POSIX di bab Utilitas Konvensi . Gaya POSIX terdiri dari opsi dengan tanda hubung tunggal diikuti dengan huruf tunggal yang menunjukkan opsi, dengan nilai argumen dipisahkan dari opsi oleh spasi.

Ada pengecualian untuk aturan - find, misalnya - tetapi ini karena preseden Unix historis.

X Windows (X11) menggunakan findopsi dasbor tunggal, seperti nama panjang.

Opsi nama ganda dengan tanda hubung ganda dipelopori oleh GNU (setelah jalan memutar menggunakan +awalan).

Lihat pertanyaan StackOverflow ini untuk diskusi tentang berbagai sistem penanganan argumen baris perintah yang dikenal - ada banyak. ( Karena ini ditulis, kekuasaan-yang-akan diputuskan pertanyaan SO 367.309 tidak cocok untuk SO. Saya sudah ditransfer jawaban untuk pertanyaan lain, Apa sintaks umum perintah Unix shell? . )

Anda dapat memperluas daftar teknik untuk mencakup git(dan sejumlah sistem lain) di mana Anda mendapatkan struktur seperti:

  • basecommand[ opsi global ] subcommand[ opsi sub-perintah ] [nama ...]

Mungkin ada banyak sub-perintah, masing-masing dengan leksikon opsi sendiri.

Tentu saja, Windows menggunakan slash ' /' yang digunakan untuk mengindikasikan opsi alih-alih tanda hubung ' -'.

JCL (untuk z / OS, dan OS / 360, dan sistem menengah) cenderung menggunakan parameter posisi yang dipisahkan oleh koma, dan umumnya dianggap tidak ramah pengguna atau antarmuka yang baik.

Jonathan Leffler
sumber
1
+1 Untuk tautan dan penyebutan yang bagus git.
maaartinus
Saya suka semua jawaban, menerima yang ini karena tautannya.
maaartinus
Pertanyaan stackoverflow sepertinya telah dihapus (atau mungkin dipindahkan) ... ada yang tahu kemana perginya? Saya penasaran untuk membacanya.
mizipzor
1
@ mizipzor: Lihat pembaruan untuk lokasi saat ini dari informasi. Lihat juga Opsi pendek / panjang dengan argumen opsi - apakah ini semacam konvensi?
Jonathan Leffler
"Tentu saja, Windows menggunakan slash '/' yang digunakan (untuk menunjukkan opsi bukan tanda hubung '-'." Mayoritas alat baris perintah Windows sekarang mendukung keduanya, dan PowerShell hanya menggunakan dash saja.
jpmc26
15

EDIT: Telah ditunjukkan bahwa gaya ini adalah GNU-isme, dan Unix yang tidak berbasis GNU cenderung menggunakan sintaks garis tunggal (khususnya, varian OS X dan BSD).

Meskipun berstatus GNU-isme, banyak program gaya Unix yang baru ditulis menggunakan gaya ini:

  • --long-option untuk nama opsi panjang,
  • -s untuk opsi pendek (satu karakter),
  • -abc untuk beberapa opsi pendek tanpa argumen (satu karakter per opsi).
  • Opsi dengan argumen:
    • --long argatau --long=arguntuk opsi lama,
    • -s arg, -sargatau (opsional) -s=arguntuk opsi pendek. Ini dapat dikombinasikan dengan opsi pendek lainnya, selama hanya yang terakhir yang memiliki argumen.
  • Opsi "semantik" yang sama dapat memiliki beberapa alias, paling sering yang pendek (lebih cepat untuk mengetik) dan yang panjang (lebih mudah diingat).

Siapa pun yang telah menggunakan shell Linux untuk jangka waktu berapa pun harus terbiasa dengan gaya 1 ini , sehingga memiliki prinsip kejutan paling tidak di sisinya. Membiarkan pengelompokan beberapa opsi pendek tanpa ambigu dengan opsi panjang juga bagus.

1 Misalnya, beberapa program menggunakan gaya ini (pada mesin Linux saya): ls, grep, man, sed, bash, dll ( EDIT: ini tampaknya GNU-isme meskipun, BSD dan OS X mesin tidak menggunakan gaya ini)

Ada beberapa perpustakaan yang dapat menangani penguraian ini untuk Anda (yang paling terkenal adalah implementasi getopt dari GNU ), hanya membutuhkan Anda untuk menentukan opsi lama dan pendek yang ada, apakah mereka mengambil argumen, dan apa yang harus dilakukan ketika suatu Opsi ditemukan. (Dan tentu saja, apa yang harus dilakukan untuk argumen posisi, yaitu argumen yang tidak memulai -dan bukan argumen untuk opsi sebelumnya)

findadalah program yang sangat lama (atau mungkin lebih mungkin: versi yang ditulis ulang dari program yang sangat lama) yang tidak dapat dengan mudah diubah untuk menggunakan sintaks baris perintah baru. Terlalu banyak skrip akan rusak, dan terlalu banyak pengguna yang terbiasa dengan sintaksis lama akan mengeluh. javackemungkinan dipengaruhi oleh gccdan teman-teman, yang juga mengikuti sintaks lama karena alasan historis.

Frits
sumber
+1 - Selain itu, ketika Anda memiliki ratusan opsi, Anda hanya perlu menjadi kreatif (misalnya saat menulis kompiler)
Tim Post
1
Anda memberi kesan bahwa semua Unices menggunakan utils GNU (yaitu, dash-dash args) dan itu salah. Mac OS X tidak memiliki dukungan untuk mereka, dan hal yang sama berlaku untuk BSD Gratis.
Martin Wickman
8
  • Argumen dengan dash-dash ( --long-arg) adalah konvensi GNU (lihat implementasi getopt mereka ).
  • Perintah POSIX tidak pernah menggunakan argumen dasbor ganda. Ini berlaku untuk sebagian besar varian Unix (Mac OS X, BSD) kecuali Linux yang menggunakan GNU secara default.

Untuk proyek Java Anda, Anda mungkin ingin memeriksa GNU getopt untuk Java atau Apache CLI . Mereka mendukung kedua konvensi.

Opsi ketiga adalah menggunakan argumen Java VM dan membiarkan runtime menguraikannya untuk Anda:

 $ java -Dcolor=blue

Dan kemudian, dalam kode:

 System.getProperty("color");

Secara pribadi, saya akan menggunakan -Didiom dan membungkus mantra Java dalam skrip shell yang menangani parsing baris perintah termasuk memeriksa classpath dll. Ini juga memudahkan pengguna asli untuk menjalankan program Java Anda.

Martin Wickman
sumber
1

Tergantung. Saya pribadi lebih suka gaya POSIX, tetapi dalam kasus Anda saya mungkin akan bertujuan untuk konsistensi dengan lingkungan di mana alat Anda akan digunakan. Ini berarti menggunakan konvensi Java untuk JAR (kecuali jika Anda berencana untuk memiliki skrip wrapper yang akan membuatnya terlihat seperti perintah Unix yang khas).

Adam Byrtek
sumber