Bisakah saya membuat `rm` hanya interaktif saat menggunakan globbing? (dalam bash atau zsh atau keduanya)

15

Setiap kali saya rmbeberapa item sekaligus dengan shell globbing dan bahkan ada kemungkinan sekecil apa pun untuk memperluas pola lebih dari yang saya harapkan, saya selalu mencoba mengingat untuk menambahkan -i, tapi (tentu saja) saya bisa lupa dan secara tidak sengaja menerbangkan sesuatu yang bermanfaat. Beberapa orang mencoba menyelesaikan masalah ini dengan alias, seperti alias rm='rm -i'tapi saya benci ide membuat rm selalu interaktif, karena dengan begitu saya akan terbiasa menggunakan -fsemua waktu, yang jelas akan mengalahkan seluruh tujuan.

Yang ingin saya lakukan adalah rmmenggunakan hanya -iketika saya menggunakan globbing, dan -ftentu saja untuk menimpanya -i, jadi saya masih bisa menerbangkan seluruh direktori dengan yang biasa rm -rf junk.

Karena itu rm *blah*akan benar-benar rm -i *blah*tetapi rm blahakan bekerja persis seperti yang diketik.

Jika ada perbedaan dalam bagaimana hal ini dapat dilakukan dalam shell yang berbeda, saya akan memilih jawaban yang memasok metode untuk bash dan zsh atas jawaban yang hanya mencakup satu atau yang lain.


Catatan : Saya sebenarnya tidak yakin ini adalah ide yang bagus; Saya hanya bertanya apakah itu mungkin. Jika Anda pikir ini adalah ide yang bodoh, saya akan sangat senang mendengar alasan di balik pendapat Anda, tetapi tolong jangan mengirim komentar seperti itu di bidang jawaban . Jawaban yang sebenarnya memberi tahu saya bagaimana melakukan ini atau menjelaskan itu / mengapa itu tidak mungkin (atau mungkin menawarkan metode alternatif untuk mendapatkan hasil yang serupa). Tetapi jika Anda ingin memberi tahu saya mengapa ini bodoh, silakan kirim sebagai komentar. Saya akan memilih komentar yang masuk akal sekalipun saya tidak setuju dengan kesimpulannya.

iconoclast
sumber
7
Beberapa saran: dengan utilitas GNU, rm -Iadalah seperti -iitu hanya memicu ketika lebih dari tiga file atau -rdilewatkan. Di bash, gunakan Ctrl-x *pintasan keyboard untuk memperluas gumpal dan memeriksanya sendiri.
jw013
2
Dengan bash, saya yakin jawabannya adalah "tidak". Dengan zsh, Anda mungkin bisa memanfaatkan noglobdengan misalnya, aliasing rm to noglob my-rm, dan kemudian memiliki my-rm menjadi skrip yang memeriksa bola dunia, memperluasnya, dan melewati -i atau tidak. Tidak yakin, tidak tahu zsh.
derobert
@derobert: Anda tentu terdengar seperti Anda tahu zsh cukup baik.
iconoclast
@iconoclast Tidak, bukan zsh, hanya Google. Anehnya, saya menemukan itu ketika mencoba menemukan cara melakukannya di bash. :-P
derobert
Jika Anda menginginkan sesuatu yang terlihat seperti rm tetapi sebenarnya berfungsi berbeda, saya harus menulis sebuah skrip (atau alias / fungsi / tombol fungsi) yang dipanggil myrmdan biarkan skrip itu melakukan hal-hal luar biasa yang Anda sukai.
Walter A

Jawaban:

9

Ini tidak mudah. Masalahnya adalah ketika Anda melakukannya:

rm -- *.txt

rm hanya melihat daftar file, bukan pola globbing yang telah diperluas oleh shell.

Yang bisa Anda lakukan adalah (zsh):

alias rm='noglob rm'

Ini memberi tahu zsh bahwa pola tidak boleh diperluas saat memanggil rm. Kemudian Anda dapat mendefinisikan kembali rm sebagai fungsi yang melakukan ekspansi itu sendiri dan menambahkan "-i" jika perlu sesuatu seperti:

'rm'() {
  [[ "$*" = *[*[?]* ]] && set -- -i "$@"
  command rm $~@
}

Masalah dengan pendekatan itu adalah bahwa "rm" baru ini tidak melihat perbedaan di antara keduanya

rm *

dan

rm '*'

Untuk menghapus file yang dipanggil *, Anda harus menulisnya:

rm [*]
Stéphane Chazelas
sumber
-1

Bekerja di bash, mungkin di shell lain. Tempatkan di.bashrc

function rm() { 
  while test "${1:0:1}" = "-"; do 
    shift
  done
  if test $# -eq 1; then 
    command rm "$1"
  else 
    command rm -i "$@"
  fi
}
selesai24
sumber
3
Anda dapat menggunakan command rmuntuk menghindari pengkodean-keras PATH. Juga, pendekatan memeriksa jumlah argumen agak tidak dapat diandalkan, karena rmdapat mengambil opsi.
jw013
1
"$ 1" harus dikutip, atau ini akan gagal jika satu file yang dikirimkan berisi spasi. @ jw013 - Anda juga dapat menghindari perintah, misalnya\rm
jordanm
@jordanm Anda benar tentang perlunya mengutip $1dengan tanda kutip ganda, tetapi salah tentang perintah yang melarikan diri. Mengutip hanya menekan alias, BUKAN mencari fungsi. Jawaban ini menyarankan fungsi, bukan alias.
jw013
1
Setidaknya pengeditan lama berfungsi - pengeditan baru membuang opsi baris perintah pengguna, yang mungkin bukan hal yang benar untuk dilakukan.
jw013
@ jw013 - Saya tidak tahu bahwa hanya berfungsi untuk pencarian alias, bukan fungsi. Terima kasih untuk informasi.
jordanm