Bagaimana cara "mengurangi" file bernama "-"?

17

Saya tidak sengaja membuat file dengan nama -(misalnya, seq 10 > -). Kemudian saya mencoba menggunakannya lessuntuk melihatnya, tetapi hanya hang.

Saya mengerti bahwa ini terjadi karena less -mengharapkan input dari stdin, sehingga tidak menafsirkan -sebagai nama file. Saya mencoba less \-tetapi tidak berhasil juga.

Jadi, apakah ada cara untuk menunjukkan lessbahwa itu -adalah file dan bukan stdin?

Yang terbaik yang bisa saya dapatkan adalah:

find -name '-' -exec less {} +
fedorqui
sumber
2
@muru terima kasih atas komentarnya, tetapi kemungkinan duplikatnya sangat spesifik sehingga saya tidak menganggapnya memenuhi syarat untuk menjadi "duplikat yang tepat". Jika itu ditulis ulang untuk sesuatu yang lebih umum seperti "cara mengakses file yang diawali dengan '-'", mungkin.
fedorqui
4
Itu bukan pertanyaan rangkap. Kasus -sendirian berbeda. -bukan pilihan.
Stéphane Chazelas
1
@terdon Saya tidak berpikir bahwa memiliki jawaban yang sama secara langsung berarti mereka adalah duplikat. Ada sebuah contoh di Meta SO: jika pertanyaan dijawab dengan "Tidak", apakah jawaban yang benar adalah "Tidak" akan menjadi duplikat? Seperti yang saya katakan sebelumnya, akan menarik untuk menulis ulang kandidat duplikat sehingga lebih umum; jika tidak, tidak masuk akal untuk mengirim pertanyaan lain ke sana seperti ini.
fedorqui
4
@terdon, tidak. Solusi yang diterima di sana tidak akan berfungsi di sini. Dan tidak, -tidak diperlakukan sebagai opsi, itu masalah yang sama sekali berbeda dari kasus argumen yang berbentuk seperti opsi.
Stéphane Chazelas
2
Tidak perlu menyertakan -antara tanda kutip tunggal suka '-'atau keluar seperti itu \-karena -bukan karakter khusus untuk shell umum (setidaknya yang sesuai dengan POSIX). Hasilnya sama.
pabouk

Jawaban:

53

Awali saja dengan ./:

less ./-

Atau gunakan redirection:

less < -

Perhatikan bahwa karena -(sebagai lawan -xatau --foo--misalnya) dianggap sebagai nama file khusus daripada opsi, berikut ini tidak berfungsi:

less -- -   # THIS DOES NOT WORK
Howard
sumber
3
BTW, itulah yang find -name '-' -exec less {} +berjalan.
Stéphane Chazelas
6
@ fedorqui, tidak hanya itu -dan ./-(atau /path/to/-atau ../to/-) adalah dua (4) jalur yang valid ke -file itu, tetapi -argumen khusus untuk less(berarti membaca dari stdin) sementara ./-tidak istimewa.
Stéphane Chazelas
2
@fedorqui find -name '-' -exec less {} +adalah bentuk non-standar untuk find . -name '-' -exec less {} +. Itu turun pohon di .dan menemukan file dan melewati path file tersebut sebagai argumen less. Ganti -exec lessdengan -exec echo lessuntuk melihat apa yang sedang dijalankan.
Stéphane Chazelas
4
@haylem, --adalah untuk menandai akhir opsi. Ini tidak akan membantu di sini. Itu -bukan opsi, itu argumen non-opsi khusus. Lihat juga unix.stackexchange.com/a/56370 , unix.stackexchange.com/a/110756
Stéphane Chazelas
3
@Haylem, coba sendiri. --ditangani oleh getopt () untuk menandai akhir opsi, -tidak dikenali sebagai opsi oleh getopt (), sehingga -akan dikenali sebagai argumen normal apakah --disediakan atau tidak. Dan sebagai argumen normal, lessseperti kebanyakan utilitas teks akan memperlakukannya sebagai makna stdin, yang tidak kita inginkan di sini.
Stéphane Chazelas
3

Catatan: jawaban saya BUKAN valid dalam kasus OP, dan hanya berlaku untuk alat yang mengikuti konvensi yang disebutkan di bawah ini dan tidak dalam kasus file bernama persis saja -(tanda hubung), yang sering juga merupakan kasus khusus untuk menentukan bacaan dari standar input diharapkan. Lihat jawaban yang diterima.

Meninggalkan ini di sini karena berisi informasi yang berguna untuk kasus-kasus lain yang mungkin seseorang temukan ketika mencari jawaban.


Dash dua kali!

Gunakan --konvensi dasbor ganda standar ( ) untuk menunjukkan argumen terakhir:

less -- -FILENAME

Contoh

$ echo "meh" > -badname
$ less -badname
Number is required after -b
$ less -- -badname # GREAT SUCCESS!

Apa?

--Argumen ini berasal dari konvensi yang didukung oleh sebagian besar implementasi utilitas shell dan alat baris perintah, dan sebagian besar shell akan menganjurkan agar Anda harus mengikutinya ketika mengimplementasikan alat CLI.

Direkomendasikan oleh Grup Terbuka

OpenGroup juga menyebutkannya di bagian Default deskripsi utilitas (v6) dari Spesifikasi Dasarnya :

Perilaku Default: [...] Utilitas standar yang tidak menerima opsi, tetapi yang menerima operan, harus mengenali "-" sebagai argumen pertama yang akan dibuang.

Persyaratan untuk mengenali "-" adalah karena menyesuaikan aplikasi memerlukan cara untuk melindungi operan mereka dari opsi sewenang-wenang yang mungkin disediakan oleh implementasi sebagai ekstensi. Misalnya, jika utilitas standar foo terdaftar tidak mengambil opsi, dan aplikasi diperlukan untuk memberinya pathname dengan tanda hubung utama, ia dapat dengan aman melakukannya sebagai:

foo -- -myfile

dan menghindari masalah dengan -m yang digunakan sebagai ekstensi.

Dan dalam Pedoman Sintaks Utilitas (v7):

Pedoman 10: Argumen pertama - yang bukan opsi-argumen harus diterima sebagai pembatas yang menunjukkan akhir dari opsi. Argumen berikut harus diperlakukan sebagai operan, bahkan jika mereka mulai dengan karakter '-'.

Direkomendasikan oleh Bash

Di sini, disarikan dari manual bash, tentang bawaannya yang mendukungnya:

Kecuali disebutkan sebaliknya, setiap perintah builtin didokumentasikan dalam bagian ini sebagai menerima opsi yang didahului oleh - menerima - untuk menandakan akhir dari opsi.

The:, true, false, dan test builtin tidak menerima opsi dan tidak memperlakukan - khususnya. Keluar, logout, break, lanjutkan, biarkan, dan shift builtins menerima dan memproses argumen yang dimulai dengan - tanpa memerlukan -. Builtin lain yang menerima argumen tetapi tidak ditentukan sebagai opsi menerima menafsirkan argumen dimulai dengan - sebagai opsi yang tidak valid dan mengharuskan - untuk mencegah interpretasi ini.

Perhatikan bahwa gema tidak mengartikan - berarti akhir dari opsi.

Bacaan Tambahan

haylem
sumber
2
1: Kebanyakan portabel dan perintah-independen solusi, mudah diingat, dan dianggap sebagai "praktek terbaik"
mveroone
2
@ Kwaio ada referensi tentang "praktik terbaik"? Hanya ingin tahu tentang hal itu.
fedorqui
24
Jawaban itu berlaku untuk argumen yang terlihat seperti opsi. Ini bukan kasus -yang bukan merupakan pilihan. Menggunakan ./-atau redirection bila memungkinkan umumnya pendekatan yang lebih baik karena menghindari jenis lain dari masalah seperti foo=bardari awkatau yang -. Lihat juga unix.stackexchange.com/a/56370 , unix.stackexchange.com/a/110756
Stéphane Chazelas
7
Seperti Stéphane mengatakan, ini tidak menjawab dengan pertanyaan. less -- -akan tetap mencoba membaca dari stdin.
Michał Politowski
5
Anda mungkin ingin menghapus jawabannya (atau memindahkannya ke pertanyaan lain karena ada referensi yang berguna di sini) atau memperjelas bahwa itu tidak berlaku untuk kasus khusus ini (dan mungkin menjelaskan mengapa yang akan lebih berguna).
Stéphane Chazelas