Anda biasanya cat /dev/null > [something]
ketika ingin menghapus konten file sambil memastikan tidak ada risiko gangguan sama sekali terhadap status file yang sebenarnya. Isi file jelas akan dihapus oleh cat /dev/null
file itu sendiri — sebagaimana adanya dan diketahui oleh sistem file tempat ia berada — akan tetap ada dengan nomor inode, kepemilikan, dan izin yang sama.
Dalam kasus file log, bisa jadi file log itu sendiri ditandai "sedang digunakan" oleh proses lain. Jadi, melakukan - misalnya - rm /var/log/messages && touch /var/log/messages
akan mengganggu proses lain dan dapat menyebabkan proses yang berjalan tersedak. Berarti suatu proses yang entah bagaimana dikunci ke nomor inode tertentu yang terhubung ke file /var/log/messages
tiba-tiba bisa panik dan berkata, “Hei! Apa yang terjadi /var/log/messages
! ”Bahkan jika file itu masih ada. Belum lagi masalah potensial dengan kepemilikan dan izin yang dibuat ulang secara tidak benar.
Karena ketidakpastian dalam penggunaan / keadaan file ini, penggunaan cat /dev/null > [something]
lebih disukai oleh admin sistem yang ingin menghapus log tetapi tidak ingin berpotensi mengganggu operasi proses yang sudah ada.
Juga, dalam konteks halaman yang Anda tautkan ke penulis menyatakan sebagai berikut:
Tidak ada yang aneh di sini, hanya satu set perintah yang bisa dengan mudah dipanggil satu per satu dari baris perintah di konsol atau di jendela terminal. Keuntungan menempatkan perintah dalam skrip jauh melampaui tidak harus mengetik ulang mereka berkali-kali.
Jadi "tidak ada yang aneh" yang penulis sebutkan berkaitan dengan keseluruhan konsep tentang apa script bash spesifik itu: Itu hanya seperangkat perintah sederhana yang dapat dengan mudah dijalankan dari baris perintah tetapi ditempatkan dalam file teks untuk menghindari harus mengetik ulang mereka berulang kali.
truncate -s 0
akan melakukan hal yang sama dan tidak terlalu idiomatis. Namun, programmer shell adalah sekelompok konservatif dan orang mungkin menemukan sistem yang cukup tua atau cukup aneh sehingga tidak memiliki perintah itu.cat /dev/null > /foo/bar
memotong file;echo "" > /foo/bar
memotongnya dan kemudian menulis satu karakter baris baru.Anda akan melakukan itu untuk memotong isi file sambil menjaga inode tetap utuh. Semua program yang membuka file untuk membaca atau menulis tidak akan terpengaruh di luar fakta ukuran file akan diatur ulang ke nol.
Alternatif palsu yang sering ditemukan adalah menghapus file kemudian membuatnya lagi:
atau yang serupa:
Masalahnya adalah metode ini tidak mencegah file lama dari terus ditulis oleh proses apa pun yang memiliki file yang dihapus terbuka pada waktu penghapusan. Alasan mengapa berada di bawah sistem file Unix, ketika Anda menghapus file, Anda hanya memutuskan tautan namanya (path) dari kontennya (inode). Inode tetap hidup selama ada proses yang terbuka untuk membaca atau menulis.
Ini menyebabkan beberapa efek negatif: log yang ditulis setelah penghapusan file hilang karena tidak ada cara mudah / portabel untuk membuka file yang dihapus. Selama proses menulis ke file yang dihapus, isinya masih menggunakan ruang pada sistem file. Itu berarti bahwa jika Anda menghapus / membuat file karena itu mengisi disk Anda, disk tetap terisi. Salah satu cara untuk memperbaiki masalah terakhir ini adalah memulai kembali proses logger tetapi Anda mungkin tidak ingin melakukannya karena layanan penting dan log perantara akan hilang secara definitif. Ada juga efek samping karena file yang Anda buat mungkin tidak memiliki izin, pemilik, dan grup yang sama dengan yang asli. Ini misalnya dapat mencegah penganalisa log untuk membaca file yang baru dibuat, atau lebih buruk, mencegah proses logging untuk menulis log sendiri.
Metode pertama,
cat /dev/null > file
mencapai tujuan dengan benar , meskipun memiliki legenda urban yang ulet,cat /dev/null
bagiannya sama sekali tidak berguna. Ini membuka file pseudo yang kosong oleh desain, gagal membaca apa pun dari itu dan akhirnya hanya keluar. Dengan menggunakan perintah ini maka buang-buang tombol, byte, panggilan sistem, dan siklus CPU dan dapat diganti tanpa perubahan fungsional dengan perintah no-op yang lebih cepat:
atau bahkan, dengan sebagian besar shell, tanpa perintah sama sekali.Biarkan saya mencoba metafora untuk menjelaskan betapa tidak berguna
cat /dev/null
itu. Katakanlah tujuan Anda adalah mengosongkan gelas.Anda pertama-tama mengeluarkan cairan apa pun darinya. Itu cukup dan tepat apa (
> file
) tidak mengingat fakta pengalihan selalu diproses terlebih dahulu.Kemudian, Anda mengambil botol kosong (
/dev/null
) dan menuangkannya ke gelas kosong (cat
). Ini adalah langkah sia-sia ...Jika Anda membaca dokumen tertaut Anda sampai akhir, Anda mungkin memperhatikan komentar di baris ini dari versi skrip yang disempurnakan:
Mereka memang punya; terlalu buruk
cat /dev/null
disimpan dalam kode.Itu berarti bahwa kode berikut ini akan berfungsi dengan semua shell umum (baik
csh
dansh
keluarga):dan ini akan bekerja dengan semua kerang menggunakan sintaks Bourne, seperti
ash
,bash
,ksh
,zsh
dan sejenisnya:Perhatikan bahwa dengan shell Bourne pre-POSIX kuno, salah satu dari perintah ini, termasuk perintah
cat /dev/null
tidak akan memotong file jika ditulis sesudahnya oleh skrip shell yang masih berjalan yang menambahkannya. Alih-alih file byte nol, itu akan menjadi file jarang dengan ukurannya tidak berubah. Hal yang sama akan terjadi jika file tersebut ditulis oleh suatu proses mencari ke posisi yang dianggapnya saat ini sebelum menulis.Hati-hati juga bahwa beberapa solusi alternatif sering disarankan untuk memotong file yang memang memiliki kekurangan.
Kedua hal berikut ini tidak melakukan pekerjaan. File yang dihasilkan tidak kosong tetapi berisi baris kosong. Ini akan memecah file log seperti
wtmp
itu menyimpan catatan lebar tetap.Yang berikutnya berdasarkan
sh
opsi BSD tidak portabel, POSIX tidak menentukan opsi yang diizinkan untuk gema sehingga Anda mungkin berakhir dengan file yang berisi baris dengan "-n
":Yang itu juga tidak portabel dengan menggunakan
sh
urutan pelarian System V. Beberapa shell akan membuat file yang berisi baris dengan "\c
":Yang itu menggunakan perintah yang dirancang untuk melakukan pekerjaan itu. Masalah yang digunakan
truncate
tidak portabel karena perintah ini, yang tidak ditentukan oleh POSIX, mungkin hilang dari sistem Unix / Linux.Akhirnya, berikut adalah beberapa alternatif yang portabel dan akan melakukan pekerjaan dengan baik:
Mencetak string kosong ke file secara eksplisit:
Menggunakan
true
perintah yang sangat setara dengan no-op satu:
meskipun lebih mudah dibaca:sumber
csh
implementasi saat ini meskipun belum tentu didokumentasikan. Daricsh
halaman manual Solaris: Null command. This command is interpreted, but performs no action.
. Saya tidak menemukan hal yang sama ditcsh
halaman manual atau yang asli BSDcsh
tetapi sintaks ini mungkin selalu berhasil.cat /dev/null
adalah untuk membuat niat Anda eksplisit./dev/null
cara yang efisien untuk menyuntikkan nol byte, lagi pula yang lebih dapat diandalkan daripada menggunakan:
atau tidak sama sekali. Di halaman ini juga, jawaban Cyrus yang singkat tetapi langsung ke titik memiliki nol suara sedangkan JakeGould yang menentang faktacat /dev/null
adalah no-op (lihat komentar kami) sudah memiliki setidaknya empat suara.>
atau:
tidak jelas. Saya setuju itu memalukan bahwa mitos telah diperbanyak karena penggunaannya.printf "" > file
yang portabel (POSIX) dan ringan seperti yang sering diimplementasikan sebagai shell builtin.Ini adalah cara rumit untuk membawa file ke ukuran nol.
sumber
csh
.: > messages
juga berfungsi.:
atau pilihantrue
yang lebih jelas untuk perintah yang tidak mencetak apa pun dan mengembalikan true.Untuk memotong file yang terbuka. Ini setara, dan lebih mudah dipahami:
(Ditambahkan -n untuk menghindari baris baru)
sumber
wtmp
case. Lihat jawaban saya yang diperbarui.bash
,-n
dinyatakan tidak akan bekerja di semua cangkang Bourne.