Pertanyaan Bagaimana saya membuat rm tidak memberikan kesalahan jika file tidak ada?


Saya sedang menulis makefile yang akan membersihkan beberapa file yang tidak berguna di akhir kompilasi. Jika target telah dibuat, tentu saja akan melewati target itu dan file yang tidak berguna mungkin tidak ada di sana. Jadi jika saya melakukan ini:

rm lexer.ml interpparse.ml interpparse.mli

Saya mungkin mendapatkan kesalahan karena salah satu file tidak ada. Apakah ada cara untuk memberi tahu rm mengabaikan file-file ini?

Saat membaca halaman manual, saya melihat opsi berikut:

 -f          Attempt to remove the files without prompting for confirma-
             tion, regardless of the file's permissions.  If the file does
             not exist, do not display a diagnostic message or modify the
             exit status to reflect an error.  The -f option overrides any
             previous -i options.

Kedengarannya seperti itu hampir apa yang saya inginkan, tetapi saya tidak benar-benar yakin tentang bagian perizinan. Apakah ada cara untuk melakukan ini?


262
2017-11-27 16:43


asal


Apakah Anda mencoba beberapa rm di kotak pasir? Sepertinya -f tidak persis apa yang Anda inginkan, terlepas dari goyangannya. - JMD
Jika izin tidak mengizinkannya, rm akan dengan -fpilihan masih mencoba untuk menghapusnya. Itu akan gagal. Itu tidak akan memberitahumu itu gagal. Berguna jika nama file adalah variabel atau gumpalan. - LawrenceC


Jawaban:


Itu -f pilihan jelas apa yang ingin Anda gunakan.

Konfirmasi tentang izin file yang dimaksud adalah ini:

$ touch myfile    
$ chmod 400 myfile
$ rm myfile       
rm: remove write-protected regular empty file `myfile'?

Begitu rm akan memperingatkan Anda jika Anda mencoba menghapus file yang tidak Anda miliki izin tulisnya. Ini diperbolehkan jika Anda memiliki izin menulis pada direktori tetapi sedikit aneh, itulah sebabnya rm biasanya memperingatkan Anda tentang hal itu.


222
2017-11-27 16:54



Sebagian besar, tetapi tidak semua sistem akan bertanya (saya pikir). Beberapa membutuhkan -i. - DaveParillo
Jika Anda ingin pesan kesalahan, tetapi bukan kode keluar kesalahan, lihat jawabannya dengan Giel Berkers. saya menggunakan set -e di semua skrip bash saya sehingga skrip keluar setelah perintah apa pun memberikan kesalahan. Saya sering menginginkan skrip untuk memberi tahu saya jika rm memberi kesalahan, tapi tetap lanjutkan. terus berlanjut. - cledoux


Solusi lain adalah ini: https://stackoverflow.com/questions/11231937/bash-ignoring-error-for-a-particular-command

Cukup tambahkan pernyataan OR setelah perintah Anda:

rm -rf my/dir || true

Dengan cara ini, ketika pernyataan # 1 gagal (melempar kesalahan), jalankan pernyataan # 2, yang sederhana saja true.


77
2018-03-09 12:39



Ini mencetak kesalahan dan melanjutkan eksekusi, yang diinginkan untuk kasus saya. - worldsayshi
Atau hanya rm -rf my/dir ||: menjadi lebih ringkas (: adalah kependekan dari true) - Godsmith
Solusi yang lebih baik menurut saya. Sangat mudah terlihat apa yang terjadi dan mengapa kode hasil diabaikan. Saya suka itu! - Mavamaarten


Saya terlambat ke pesta, tapi saya menggunakan ini sepanjang waktu. Dalam makefile, tambahkan - ke awal baris untuk mengabaikan nilai kembalian dari baris itu. Seperti ini:

-rm lexer.ml interpparse.ml interpparse.mli

69
2017-12-23 23:12



Ini masih akan mencetak kesalahan ke konsol, yang melatih Anda untuk mengabaikan kesalahan dalam output make, yang mungkin bukan yang Anda inginkan. rm -rf adalah pilihan yang lebih baik menurut saya. - Godsmith
@Godsmith Saya lebih suka mengabaikan kesalahan daripada memaksa penghapusan rekursif. Ini bisa sangat nakal. Dan +1 untuk sintaks khusus makefile - Daishi
Jika rm -rf bisa "nakal", itu berarti Anda menggunakan make di luar direktori di bawah kontrol versi. Mengapa? - Godsmith
Tolong berikan tautan ke dokumentasi. Bisa menemukan deskripsi fitur ini. - George Sovetov
@GeorgeSovetov gnu.org/software/make/manual/make.html#Errors - Robert Li


Jika Anda tidak ingin menggunakan opsi -f, alternatifnya adalah:

rm filethatdoesntexist 2> /dev/null 

Ini hanya akan mencegah kesalahan dicetak.


8
2018-06-12 19:46



Sayangnya ini masih akan memberikan kode kesalahan keluar. - Shaun McDonald


Jika Anda menemukan beberapa cara gumpal nama file, rm tidak akan mengeluh jika tidak dapat menemukan kecocokan. Jadi sesuatu seperti itu lexer.m* interpparse.*, dll. harus bekerja untuk Anda (hati-hati Anda tidak terlalu banyak menghapus, tentu saja). Juga, -f adalah cara yang masuk akal untuk pergi, selama Anda tidak berharap bahwa izin file akan menyelamatkan Anda dari menghapus file yang tidak Anda inginkan - jika Anda tidak ingin menghapusnya, jangan taruh di daftar.


7
2017-11-27 16:48



Para globbing akan keluar dari pertanyaan karena ada file lexer.mll yang tidak ingin saya hapus. Terima kasih telah menunjukkan mengapa -f masuk akal. Saya kira saya cenderung terlalu berhati-hati setelah terlalu banyak salah kaprah sudo rm -rf . - Jason Baker
Bahkan tidak lebih ketat lexer.m? ...? Itu akan menangkap lexer.ml dan lexer.mz, tapi tidak lexer.mll atau lexer.mla. - JMD
@ JMD: Saya kira itu tergantung pada shell Anda dan dukungan pencocokan pola apa yang ditawarkannya untuk globbing. - Nick Bastin


Opsi -f berarti Anda tidak akan ditanyai jika sesuatu tidak seperti yang diharapkan. Itu tidak berarti bahwa perizinan tidak diperhitungkan.

Jika Anda tidak memiliki cukup hak untuk menghapus file, itu tidak akan dihapus.

TAPI, jika Anda memiliki hak yang cukup untuk mengubah hak istimewa, file Anda akan dihapus. Ini adalah kasus ketika Anda adalah pemilik file dengan izin baca untuk pemilik (-r --------). Sebagai pemilik, Anda bisa chmod u+w, lalu hapus: rm -f akan menghapus file itu.


5
2017-11-27 19:27





Mungkin bisa membantu garis yang serupa dengan:

touch fakefile.exe fakefile.o && rm *.o *.exe

Saya tahu bahwa ini tidak terlalu pintar, tetapi melakukan pekerjaan.


3
2018-03-11 10:36





Sebuah alternatif:

RmIfIsFile() {  for f in "$@"; do [ -f $f ] && rm $f; done; };  RmIfIsFile lexer.ml interpparse.ml interpparse.mli

Makefile yang terlalu buruk tidak dapat berbagi definisi fungsi shell di seluruh baris.


2
2017-11-27 17:44



Sudahkah Anda mencoba menggunakan \ (backslash) di akhir baris untuk membiarkannya berlanjut pada baris berikutnya? - some
@some: Ya, mereka dapat tersebar di beberapa baris, tetapi untuk membagikannya ke seluruh resep Anda harus memasukkan definisi dalam variabel make. - reinierpost