Apa yang dianggap praktik terbaik untuk penggunaan / bantuan pencetakan (--help)?

13

Saat menulis alat untuk CLI UNIX, bagaimana saya harus membuat program mencetak bantuan dan / atau penggunaan?

Saya biasanya menggunakan fprintf(stderr, "help text here");, tetapi ada beberapa masalah dengan itu.

  • Pertama, saya tidak yakin, apakah saya harus menggunakan stderr. Apakah itu OK, atau haruskah saya gunakan stdout?
  • Seperti yang dapat Anda bayangkan, teks bantuannya cukup panjang, tergantung pada berapa banyak opsi yang dimiliki alat ini. Sekarang, saya biasanya, cukup masukkan beberapa "strings like that\n"di parameter kedua. Namun ini, mengisi kode sumber saya dengan lima puluh atau lebih baris teks bantuan. Tidak mudah dikelola sama sekali. Apa yang harus saya lakukan?
  • Ketika sebuah alat tidak ditulis dalam bahasa C atau seperti C, saya cenderung menggunakan di sini-docs jika memungkinkan (paling jelas dengan Perl). Saya tidak bisa menggunakannya di C, tetapi apakah ada sesuatu seperti itu, yang bisa saya gunakan?
  • Saya sedang mempertimbangkan meletakkannya di headerfile.hdalam #define HELP "help text here", saya belum pernah melihatnya di alam liar, tidak tahu apakah saya benar-benar harus menggunakannya.

Idealnya, saya bisa meletakkan teks dalam file eksternal, dan memasukkannya. Menggunakan #includeuntuk itu tampaknya salah. Apa yang harus saya lakukan?

Idenya adalah, untuk memiliki teks bantuan, yang mudah dikelola. Memiliki itu di dalam kode sumber tidak benar-benar nyaman.

polemon
sumber
1
Apa yang buruk tentang 50 baris dalam kode sumber Anda? Taruh saja di akhir. Ini tidak seperti Anda harus mengacaukannya secara teratur.
whatsisname
2
@whatsisname, bantuan untuk normal dan longopts Saya akhirnya memiliki sekitar 200 baris string dalam kode sumber. Selain itu, saya kira ini bukan praktik terbaik, dll. Pasti ada cara yang lebih efisien untuk memasukkan teks bantuan, dll.
polemon

Jawaban:

8

Menginspirasi diri Anda dari internal platform target Anda

Lihatlah kode sumber BSD. Sebagai contoh, berikut adalah:

  • usage(void)untuk /usr/bin/unamealat [ sumber ] NetBSD :

    usage(void)
    {
        fprintf(stderr, "usage: uname [-amnprsv]\n");
        exit(EXIT_FAILURE);
    }
    
  • usage(void)untuk /usr/bin/telnet[ sumber ] NetBSD

  • usage(void)untuk /bin/ls[ sumber ] OpenBSD

Lihat alternatifnya

Dan putuskan sendiri apakah mereka lebih baik atau lebih buruk. Anda dapat menggunakan Google CodeSearch untuk menemukan orang lain, seperti:

  • Penggunaan [ sumber ] SkyLoad

Seperti yang Anda lihat, gaya yang berbeda antara ini dan alat-alat terintegrasi sistem BSD tercantum di atas. Itu tidak berarti Anda harus mengikuti yang satu atau yang lain. Tetapi biasanya ada baiknya untuk melihat-lihat, dan puas dengan solusi yang konsisten.

Solusi non-standar untuk 50 jalur bantuan ...

Jika Anda tidak ingin menghindari 50 baris teks, Anda bisa membaca bantuan dari file teks (dalam teks biasa, atau mungkin langsung menguraikan mansumbernya jika Anda membuatnya). Saya menemukan cara yang agak elegan (seperti Anda bahkan dapat melihat dokumen teks), namun untuk program sistem inti yang akan membuat mereka secara inheren tidak aman dan memperkenalkan titik kegagalan. Orang lain akan berpendapat itu berat untuk suatu usageatau helppesan, tetapi tidak seperti ini disebut dalam loop ketat cepat ...

Jika ragu, ikuti para raksasa.

haylem
sumber
9

Saya menggunakan stdout, karena bantuan bukan kesalahan.

Jika ini sangat membantu dalam C, saya mencoba meniru di sini-docs:

printf("This is the help for MyWonderfulApp\n"
       "Options are:\n"
       "    --help: display what you are reading now\n"
       "    --quiet: output nothing\n");

Tetapi sebagian besar waktu saya menulis manhalaman menggunakan nroff -mantag khusus. Bantuan dalam aplikasi hanya terdiri dari merujuk ke manhalaman itu.

mouviciel
sumber
Tetapi bantuan belum tentu merupakan output standar yang diinginkan, bukan? Bagaimana dengan stdlog?
greyfade
@ Greyfade: Apakah stdlogstandar C?
mouviciel
@mouviciel: ... Saya pikir itu. Saya rasa tidak. C ++ memiliki aliran standar terkait ( cin, cout, cerr, dan clog), jadi saya kira saya pikir stdlogadalah dalam standar C. Salahku.
greyfade
2

Jika aku akan kamu, aku baru saja membuka sumber grep, tail, cat, your_other_favorite_unix_shell_commanduntuk melihat bagaimana hal itu dilakukan di sana. Saya cukup yakin cara mereka dipikirkan dengan baik dan dapat dipertahankan oleh banyak orang.

Tentang stderratau stdout. Ini sangat sederhana, jika ada kesalahan - tulis stderr, jika hanya info - stdout. Misalnya, jika saya menjalankan alat Anda dengan opsi yang salah, Anda mungkin ingin menampilkan kesalahan, katakanlah Use --help for usage, ini termasuk dalam stderr. Jika saya menjalankan alat Anda dengan opsi yang valid --help, silakan gunakan stdout.

Jika itu preferensi Anda untuk tidak memiliki string bantuan lama di dekat kode Anda, jangan. #define dalam file header baik-baik saja, tapi itu benar-benar pilihan pribadi. Jika saya harus membaca kode alat baris perintah saya lebih suka string bantuannya berada di dalam file yang menangani opsi yang disediakan oleh pengguna.

devmiles.com
sumber
2
Itu tidak menjawab pertanyaannya.
Mavrik
Hm, ada apa dengan minusnya? Untuk apa?
devmiles.com
@ Malrik: paragraf pertama tidak.
haylem
1

Saya menggunakan perpustakaan gnu getopts . Untuk contoh dengan bantuan, lihat contoh proyek ini , khususnya metode utama di bagian bawah parser.y .

Karena dibungkus dengan kurung kurawal, editor vim yang saya gunakan dapat melipat garis-garisnya, dan saya bahkan tidak menyadarinya ketika saya tidak perlu melakukannya.

Spencer Rathbun
sumber
1

Jika saya menggunakan C atau memilih untuk tidak bergantung pada Boost libraries, maka saya tetap menggunakan GNU getopt. Kalau tidak, saya lebih suka Opsi Program Peningkatan yang mencetak bantuan secara otomatis.

Saya juga mempertimbangkan untuk menebak opsi yang tepat sebagai salah satu praktik terbaik dalam hal penanganan opsi. Saya mempelajarinya dari Git dan sekarang menggunakan hal yang sama dalam proyek saya. Ini pada dasarnya menggunakan jarak Damerau – Levenshtein untuk mencetak kecocokan terbaik jika pengguna memasukkan beberapa opsi baris perintah yang tidak dikenal.

Saya menulis sedikit artikel tentang ini yang dapat Anda gunakan sebagai contoh.

Semoga bermanfaat :)


sumber
1

Jelas, menulis halaman lubang dalam kode << atau printf (cout) rumit, terutama jika Anda perlu mengubah dan mengisi ulang paragraf Anda. Oleh karena itu, jelas merupakan ide bagus untuk mengedit teks itu dalam file yang terpisah, menggunakan misalnya emacs di mana Anda dapat lebih mudah memformat teks Anda.

Kemudian Anda dapat menggunakan skrip sed berikut untuk mengkonversi file teks itu ke file header C legal:

s/\"/\\\"/g
s/$/\\n"/
s/^/"/
1i\
const char *helpStr = 
$a\
;

Kemudian, setelah #include -ing file header Anda ke kode sumber Anda, Anda dapat hanya menulis teks menggunakan

cout << helpStr;
pengguna29809
sumber