Mengapa saya menerima duplikat switch?

16

Saya ingin tahu - apakah ada perbedaan antara ls -ldan ls -lllllllllllllllllllllllllllll?

Outputnya tampaknya sama dan saya bingung mengapa lsmemungkinkan switch duplikat. Apakah ini praktik standar di antara sebagian besar perintah?

Mike B
sumber

Jawaban:

17

Jawaban singkat :

Karena diprogram untuk mengabaikan beberapa penggunaan bendera.

Jawaban panjang:

Seperti yang Anda lihat dalam kode sumber dari ls, ada bagian dengan fungsi getopt_long()dan kasus switch besar:

1648       int c = getopt_long (argc, argv,
1649                            "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",
1650                            long_options, &oi);
      ....
1654       switch (c)
1655         {
      ....
1707         case 'l':
1708           format = long_format;
1709           break;
      ....
1964     }

Fungsi getopt_long()membaca semua parameter yang diberikan ke program. Dalam hal jika -lvariabel formatdiatur. Jadi, ketika Anda mengetik banyak -lllllllllvariabel itu ditetapkan beberapa kali, tetapi itu tidak mengubah apa pun.

Yah, itu mengubah satu hal. Pernyataan switch case yang sangat besar ini harus dijalankan berkali-kali, karena beberapa -lflag. lsperlu lebih lama untuk menyelesaikan dengan beberapa -lflag. Tapi kali ini tidak layak disebut. =)

kekacauan
sumber
11
Atau dengan kata lain, menolak mereka akan lebih berguna bagi programmer daripada mengabaikan mereka.
Markus
1
+5.5 untuk mengatakan apa yang akan saya katakan, +0.5 untuk pergi ke sumber.
CVn
21

Karena itu hal yang benar untuk dilakukan. Misalkan Anda memiliki skrip yang melakukan sesuatu seperti:

ls $LS_OPTIONS -l "$dir"

dimana mungkin yang $LS_OPTIONSsudah berisi -l. Ini akan menjadi kontra-intuitif dan menjengkelkan untuk perintah ini untuk menghasilkan kesalahan dan akan membutuhkan logika tambahan dalam skrip untuk menghindarinya.

-lmungkin bukan contoh terbaik untuk ini, tetapi mudah-mudahan Anda dapat melihat bagaimana konsep ini berlaku secara umum. Contoh yang jauh lebih baik adalah opsi kompiler $CFLAGSyang dapat menduplikasi opsi eksplisit dalam permintaan khusus dari kompiler.

R .. GitHub BERHENTI MEMBANTU ICE
sumber
4
Hal yang sama juga bisa terjadi jika Anda telah menetapkan alias yang memanggil lsdengan beberapa set opsi.
kasperd
1
@kasperd: Ya. Meskipun memasukkan alias -lAnda lssepertinya ide yang buruk, masalah yang sama kemungkinan akan muncul dengan opsi yang bagus di lsalias interaktif seperti -patau --color=auto.
R .. GitHub BERHENTI MEMBANTU ICE
1
Alias ​​tidak harus dipanggil ls. llmungkin alias untuk ls -l, dan pada sistem dengan alias itu, saya bisa mengetik ll -lart.
kasperd
11

lsbukan bashperintah, tetapi eksekusi terpisah yang kebetulan Anda luncurkan bash. Yang mengatakan, -lhanyalah jenis bendera Boolean, yang jika ada menyebabkan lsmenggunakan format gaya panjang untuk output. Sebagian besar program hanya akan mengabaikan banyak kegunaan ( ls -llsama dengan ls -l -l) dari flag-flag tersebut, walaupun ada beberapa pengecualian (sebagai contoh, jika -vberarti 'verbose', maka suatu program dapat menginterpretasikan beberapa kegunaan untuk berarti "bahkan lebih bertele-tele").

chepner
sumber
2
Contohnya -vvvadalah ssh.
Bernhard
Atau bahkanaptitude moo
Ruslan
8

Alias ​​Shell akan sangat mengganggu jika perintah seperti lstidak mengizinkan opsi berulang.

Misalkan Anda punya

alias ls='ls --color=auto'
alias rm='rm -i'

Kemudian, jika flag yang bertentangan tidak diizinkan, itu akan menjadi kesalahan untuk mengeluarkan perintah seperti ls --color=neveratau ls --color=autoatau rm -i.

Oleh karena itu, perintah ini dirancang untuk membiarkan flag yang lebih baru menimpa yang sebelumnya.

200_sukses
sumber
Sakelar yang konflik terkadang tidak diizinkan. (Coba rsync dengan keduanya --inplacedan --delay-updates, misalnya.) Beberapa alat ambil saja yang terakhir; rm -ifmungkin contoh yang bagus di sana. Tetapi tidak ada konflik dalam opsi ls-l, karenanya ls -ldan ls -llbukan masalah, dan itu tidak mempengaruhi eksekusi secara signifikan. Komputer bagus dalam pengulangan yang mematikan pikiran.
CVn