Bagaimana cara membuat file yang dinamai seperti argumen baris perintah?

29

Saya bertanya-tanya bagaimana cara membuat file bernama bendera, misalnya, jika saya ingin membuat folder bernama -a, perintah apa yang akan melakukan trik?

Saya mencoba mkdir '-a',, mkdir \-adan tidak ada yang berhasil. Saya di Ubuntu.

MYV
sumber
13
Jawabannya di sini sangat bagus, tapi saya tidak bisa memikirkan alasan non-troll ingin melakukan ini ...
evilsoup
@evilsoup Beberapa orang suka membuat awalan folder sehingga mereka tetap di bagian atas dalam daftar yang diurutkan secara alfanumerik. Tapi itu satu-satunya alasan yang bisa kupikirkan, jujur.
slhck
@ slhck Saya tahu setidaknya satu kursus penyuntingan video di mana mereka mendorong siswa untuk menambahkan ruang kosong ke direktori proyek mereka sehingga mereka akan muncul di bagian atas di iMacs komunal. Ini jelek dan menyebabkan eskalasi lucu, tapi setidaknya itu tidak akan berpotensi merusak sistem ...
evilsoup
3
Sebagian besar di sini untuk kepentingan akademis.
MYV
5
Komik wajib: beesbuzz.biz/d/20110224.php
fluffy

Jawaban:

49

Panggil perintah seperti ini:

mkdir -- -a

The --berarti bahwa opsi berakhir setelah itu, sehingga -aakan ditafsirkan secara harfiah dan bukan sebagai pilihan untuk mkdir. Anda akan menemukan sintaks ini tidak hanya di mkdir, tetapi setiap utilitas yang sesuai dengan POSIX kecuali untuk echodan test. Dari spesifikasi :

Argumen - harus diterima sebagai pembatas yang menunjukkan akhir opsi. Argumen berikut harus diperlakukan sebagai operan, bahkan jika mereka mulai dengan karakter '-'. Argumen - tidak boleh digunakan sebagai opsi atau sebagai operan.

Menggunakan --sebagai pengamanan dianjurkan untuk hampir semua tindakan di mana Anda berurusan dengan nama file dan ingin memastikan mereka tidak melanggar perintah, misalnya ketika memindahkan file dalam satu lingkaran, Anda mungkin ingin memanggil yang berikut, sehingga file bernama -iisn ' t (dalam?) diurai dengan benar sebagai opsi:

mv -- "$f" new-"$f"
slhck
sumber
Kelemahan dari pendekatan ini adalah tepatnya bahwa ia menghentikan pemrosesan opsi. Sebagai contoh mkdir sederhana, itu bekerja dengan sangat baik; jika Anda benar-benar membutuhkan opsi untuk mengikuti nama file pada baris perintah, itu tidak akan berfungsi sama sekali.
CVn
1
Tentu saja — ada kerugian untuk semuanya. Dalam kasus di mana Anda berurusan dengan nama file diselingi dengan opsi, solusi Amos akan menjadi satu-satunya alternatif yang waras yang bisa saya pikirkan, tetapi itu benar-benar tergantung pada bagaimana alat mem-parsing opsi.
slhck
1
Karena OP berbicara tentang membuat file dengan nama "seperti argumen baris perintah" (mari kita asumsikan berarti nama yang dimulai dengan tanda hubung), saya tidak berpikir itu asumsi yang sama sekali tidak masuk akal. Ambil cc -o -myfile -Wall -myfile.csebagai contoh yang hanya sedikit dibuat-buat. Editor mana pun yang layak diberi garam harus dapat menyimpan ke file bernama -myfile.cjika Anda memintanya, tetapi kompiler C mungkin tidak akan melakukan apa yang Anda inginkan ketika diberi daftar opsi seperti itu.
CVn
1
@Maksim Misalnya perintah yang memerlukan opsi untuk mengatur nama input atau output, seperti ccperintah yang Michael berikan di atas, yang memiliki -oopsi untuk menentukan file output.
slhck
1
Contoh loop adalah mengapa Anda harus selalu menggunakan sesuatu seperti for f in ./*; do...daripadafor f in *; do...
evilsoup
21

Cara paling sederhana yang harus bekerja dengan program yang masuk akal adalah dengan menggunakan nama jalur relatif di depan -, misalnya mkdir ./-aakan membuat direktori yang disebut -adalam direktori kerja saat ini.

Contoh paling umum menggunakan "trik" ini adalah ketika Anda ingin menghapus file yang dimulai dengan tanda hubung, sehingga Anda dapat melakukannya rm ./-a.

Amos Shapira
sumber
3
Itu tentu saja hanya berhasil jika Anda bekerja dengan jalur file, dan bukan opsi baris perintah sewenang-wenang yang diuraikan sebagai string. Tetapi jika tidak, awalan ./selalu merupakan ide yang bagus — bayangkan Anda membuat file yang dipanggil -rflalu Anda panggil rm *.
slhck
1
Sslhck Untuk banyak orang yang mungkin terlihat bercanda. Tetapi saya telah melihat cukup banyak kasus di mana hal semacam ini memusnahkan (bagian dari) server. Anda tidak dapat cukup memperingatkan orang tentang bahaya file yang dimulai dengan tanda hubung. Satu tempat saya bekerja bahkan memilikinya sebagai aturan resmi: Jangan pernah membuat file yang namanya dimulai dengan "-f" atau "-r".
Tonny
1
Yang ini harus menjadi jawabannya: itu adalah satu-satunya cara portabel ( --tidak dimengerti oleh setiap perintah, hanya beberapa)
Olivier Dulac
@OlivierDulac Saya pikir --itu hal yang bash, jadi itu harus bekerja untuk semua program?
gsingh2011
@ gsingh2011 tidak, kode yang memutuskan apakah "-" dianggap sebagai penanda "ujung bendera" tinggal di aplikasi dan terserah masing-masing aplikasi untuk memutuskan apakah itu memperlakukannya seperti itu.
Amos Shapira
4

Alasan mengapa mkdir '-a', atau mkdir \-atidak berhasil adalah karena kedua metode ini (menggunakan tanda kutip atau garis miring terbalik) digunakan untuk mencegah shell Anda (kemungkinan bash) memberi mereka arti khusus. Karena -atidak berarti sesuatu yang istimewa pada shell, ini tidak memiliki efek pada bagaimana ia diteruskan mkdir.

Sejauh mkdirmenyangkut, ia menerima daftar argumen dari shell, dan itu tidak bisa mengatakan apakah Anda memasukkannya ke dalam tanda kutip atau tidak, atau apakah ada backslash. Itu hanya melihat satu argumen -a. Itu sebabnya Anda perlu --seperti yang dijelaskan dalam jawaban lain.

hammar
sumber
-3

Selain jawaban dari "slhck" ada trik lain yang kadang-kadang berfungsi:

Masukkan nama file dalam 2 set qoutes (berbeda) seperti "'-a'"atau '"-a"'.

Apakah ini berfungsi atau tidak tergantung pada program, tetapi ini merupakan pilihan terakhir jika program tidak mendukung --fitur POSIX .
Metode POSIX selalu disukai karena 100% dapat diandalkan.

Tonny
sumber
"Metode POSIX selalu disukai karena 100% dapat diandalkan." Menggunakan --untuk menghentikan pemrosesan opsi juga mengasumsikan bahwa Anda tidak memerlukan opsi apa pun untuk mengikuti nama file, yang tidak selalu demikian.
CVn
@ MichaelKjörling Tentu saja ... Tapi saya berasumsi itu sudah jelas.
Tonny
4
Ini akan membuat file bernama '-a'atau "-a", setidaknya pada sistem tipe BSD
nohillside
4
Dapatkah Anda mengutip OS / shell di mana ini tidak bekerja?
nohillside
1
jika itu berhasil, tampaknya Anda akan memiliki masalah yang agak signifikan berurusan dengan file dengan nama yang dikelilingi oleh tanda kutip.
muhmuhten