Apakah ada kerugian dari pengaturan `noclobber`?

20

Mengingat bahwa zshdapat mengalahkan semua file yang diberikan perintah:

>*

Saya berpikir bahwa menetapkan opsi noclobberakan menjadi ide yang bagus.

Saya selalu dapat menggunakan >| filejika saya ingin menggunakan perilaku clobber default di bash dan zsh. (zsh juga memungkinkan sintaks alternatif >!file).

Saya menduga noclobbertidak disetel secara default karena kompatibilitas POSIX, tetapi hanya untuk memastikan:

Apakah ada kelemahan pada pengaturan noclobber?

Apakah ada untuk mengatur noclobberhanya untuk shell interaktif?

Tom Hale
sumber
3
Saya terkejut zsh setidaknya tidak memperingatkan tentang itu, mengingat bahwa itu memperingatkan tentang sesuatu seperti rm *...
ilkkachu

Jawaban:

24

Alasannya noclobbertidak diatur secara default adalah tradisi. Sebagai masalah desain antarmuka pengguna, merupakan ide yang baik untuk membuat "buat file baru ini" tindakan yang mudah dan untuk menempatkan rintangan ekstra tindakan yang lebih berbahaya "baik membuat file baru atau menimpa file yang sudah ada". Maka itu noclobberadalah ide yang baik ( >untuk membuat file baru, >|untuk berpotensi menimpa file yang sudah ada) dan kemungkinan akan menjadi default jika shell telah dirancang beberapa dekade kemudian.

Saya sangat menyarankan untuk menggunakan yang berikut ini di file startup shell interaktif Anda ( .bashrcatau .zshrc):

set -o noclobber
alias cp='cp -i'
alias mv='mv -i'

Dalam setiap kasus (pengalihan, penyalinan, pemindahan), tujuannya adalah untuk menambahkan rintangan tambahan ketika operasi mungkin memiliki efek samping menghapus beberapa data yang ada, meskipun menghapus data yang ada bukanlah tujuan utama operasi. Saya tidak memasukkan rm -idaftar ini karena menghapus data adalah tujuan utama rm.

Perhatikan itu noclobberdan -imerupakan jaring pengaman . Jika mereka memicu, Anda telah melakukan kesalahan . Jadi jangan gunakan itu sebagai alasan untuk tidak memeriksa apa yang Anda timpa! Intinya adalah Anda harus memeriksa bahwa file output tidak ada. Jika Anda diberitahu file exists: fooatau overwrite 'foo'?, itu berarti Anda melakukan kesalahan dan Anda harus merasa buruk dan lebih berhati-hati. Secara khusus, jangan terbiasa mengatakan yjika diminta untuk menimpa (bisa dibilang, alias seharusnya alias cp='yes n | cp -i' mv='yes n | mv -i', tetapi menekan Ctrl+ Cmembuat output terlihat lebih baik): jika Anda bermaksud menimpa, membatalkan perintah, memindahkan atau menghapus output file, dan jalankan perintah lagi.

Penting juga untuk tidak membiasakan diri memicu keselamatan tersebut karena jika Anda melakukannya, suatu hari Anda akan berada di mesin yang tidak memiliki konfigurasi Anda, dan Anda akan kehilangan data karena perlindungan yang Anda hitung pada saat itu tidak di sana.

noclobberhanya akan ditetapkan untuk shell interaktif, karena .bashrcatau .zshrchanya dibaca oleh shell interaktif. Tentu saja Anda tidak boleh mengubah opsi shell dengan cara yang akan memengaruhi skrip, karena skrip tersebut dapat merusak skrip tersebut.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
6
rmmemiliki opsi -Iyang saya gunakan dan rekomendasikan: "meminta sekali sebelum menghapus lebih dari tiga file, atau ketika menghapus secara rekursif; tidak terlalu mengganggu daripada -i, sambil tetap memberikan perlindungan terhadap sebagian besar kesalahan"
Reid
9
Saya sangat menyarankan untuk tidak menggunakan kembali cp dan mv seperti itu. Namun, menggunakan -isebagai argumen default untuk mereka adalah ide yang bagus, tetapi harus diterapkan pada nama alias yang berbeda , bukan yang asli (misalnya saya selalu meletakkan alias copy="cp -i"dan alias move="mv -i"di .bashrc saya). Mengapa? Karena mode kegagalan. Apa yang terjadi ketika Anda menggunakan mesin atau pengguna lain yang tidak memiliki alias cp / mv? File berpotensi ditimpa secara tidak sengaja (mungkin tidak terdeteksi!). Mode kegagalan yang sesuai dengan copy / move alias: shell mengeluh bahwa ia tidak mengenali perintah.
hlovdal
1
Ada juga mode kegagalan tambahan untuk cp / mv alias: ketika menulis skrip shell seseorang yang digunakan untuk cp = "cp -i" alias bisa menulis perintah cp salah mengharapkannya berperilaku seperti dalam mode interaktif karena tidak ada perbedaan nama. Sebaliknya, setiap kali saya menulis "copy somefile / some / where" saya tahu bahwa saya menggunakan alias dan bukan perintah cp secara langsung. Dan bahkan jika saya harus meletakkan salinan ke file shell itu akan gagal dengan cara yang sama seperti untuk shell dengan alias hilang.
hlovdal
1
Jadi TL; DR saran ke default untuk menggunakan -iargumen untuk cp dan mv sangat bagus, tetapi saran untuk menggunakan kembali nama cp dan mv sangat buruk. Sangat buruk saya harus memberikan jawaban suara turun. Harap ubah untuk menggunakan nama alias yang berbeda dan saya akan memberikan suara.
hlovdal
1
@ TomHale Anda bisa menggunakan alias RM='command rm', yang akan memberitahu zsh untuk menggunakan perintah eksternal, rmbukan alias. Dengan begitu Anda tidak harus bergantung pada --interactive=nevermenggantikan yang sebelumnya -i.
Adaephon
6

Mengatur noclobberopsi shell di ~/.bashrc(untuk bash) atau ~/.zshrc(atau lebih tepatnya $ZDOTDIR/.zshrc, untuk zsh) akan membuatnya aktif dalam sesi shell interaktif.

Kerang (skrip) non-interaktif tidak membaca file-file ini.

Opsi shell biasanya tidak diwarisi dari shell induk.

Ini berarti bahwa Anda harus dapat mengatur opsi di file-file itu tanpa mengubah perilaku di skrip yang ada, kecuali skrip secara eksplisit sumber file-file tersebut.

Satu-satunya downside dari melakukan ini yang dapat saya lihat adalah bahwa Anda akan berulang kali lupa bahwa Anda telah menetapkan opsi, setidaknya di awal. Kemudian, seperti semua hal-hal semacam ini, Anda akan mulai terbiasa menggunakan >|, bahkan dalam kasus-kasus di mana Anda sebenarnya tidak ingin merusak file (seperti halnya orang dengan alias rm, cpdan mvdengan -iopsi selalu diset, akhirnya mulai selalu menggunakan -fdi baris perintah).

Kusalananda
sumber
2
Dengan bash, opsi diwarisi jika $SHELLOPTS( $BASHOPTSuntuk shoptyang) ada di lingkungan (bukan sesuatu yang umumnya ingin Anda lakukan karena alasan semacam ini).
Stéphane Chazelas
3

Kelemahannya adalah, jika Anda menjadi terbiasa dengan noclobberaktif, suatu hari Anda akan menggunakan sistem yang tidak aktif dan Anda akan dengan senang hati menjalankan perintah yang berpotensi berbahaya, mengharapkan noclobberuntuk menyelamatkan Anda ... dan tidak akan. Dan kemudian Anda harus berharap bahwa ada cadangan yang cukup baru untuk memulihkan data yang Anda hancurkan karena Anda menganggap Anda akan diminta konfirmasi terlebih dahulu.

Dave Sherohman
sumber
Tentu, suatu hari Anda akan menggunakan sistem yang tidak aktif. Saat Anda menggunakan sistem yang tidak dikenal, Anda harus sangat berhati-hati dan memastikan bahwa cadangannya mutakhir sebelum melakukan sesuatu yang berpotensi merusak seperti mengarahkan kembali keluaran ke file.
Gilles 'SO- berhenti bersikap jahat'