Ketika Anda mencoba untuk memodifikasi file tanpa izin tertulis di dalamnya, Anda mendapatkan kesalahan:
> touch /tmp/foo && sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Sudoing tidak membantu, karena menjalankan perintah sebagai root, tetapi shell menangani pengalihan stdout dan membuka file seperti Anda:
> sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Apakah ada cara mudah untuk mengarahkan stdout ke file yang Anda tidak punya izin untuk menulis, selain membuka shell sebagai root dan memanipulasi file dengan cara itu?
> sudo su
# echo test > /tmp/foo
shell
permissions
io-redirection
sudo
io
Michael Mrozek
sumber
sumber
chown
mengganti pemilik; itu hanya sebuah contohJawaban:
Ya, menggunakan
tee
. Jadiecho test > /tmp/foo
menjadiAnda juga dapat menambahkan (
>>
)sumber
echo test | sudo tee /tmp/foo > /dev/null
Untuk mengganti konten file dengan output
echo
(seperti>
operator pengalihan shell).Untuk menulis ke dalam file (di awal, meskipun Anda dapat menggunakan
seek
untuk output pada offset yang berbeda) tanpa memotong (seperti1<>
operator shell Bourne):Untuk menambahkan file (seperti
>>
), dengan GNUdd
:Lihat juga GNU
dd
'sconv=excl
untuk menghindari clobbering file yang ada (seperti denganset -o noclobber
di kerang POSIX) danconv=nocreat
untuk berlawanan (hanya memperbarui file yang ada).sumber
echo test | sudo tee /tmp/foo >/dev/null
untuk membuang output.dd
tidak dapat diandalkan untuk itu kecuali Anda menggunakan opsi khusus GNU yang tidak jelasiflag=fullblock oflag=fullblock
, yang menghapus keanggunan jawaban ini. Saya akan tetap dengantee
.dd
bisa sangat berbahaya (jika tidak dikatakan: menghancurkan) jika hanya sedikit kesalahan dibuat. Jadi untuk pengguna baru, saya lebih suka merekomendasikantee
metode ini untuk berada di pantai yang aman.dd of=file
sendirian (tanpacount
/skip
...), itu dapat diandalkan.iflag=fullblock
tidak diperlukan karena di sinidd
menulis tentang keluaran apa yang telah dibaca pada input. Tidak masalah jika itu bukan blok penuh.tee
mungkin pilihan terbaik, tetapi tergantung pada situasi Anda sesuatu seperti ini mungkin cukup:sumber
eval
bukannya sederhanash -c
; -i, yang akan mengubah dir kerja Anda; menjalankan seluruh perintah sebagai root, yang dapat mengubah perilaku itu atau mungkin menimbulkan risiko yang tidak perlu. mengapa ini pernah mendapat dukungan?Sementara saya setuju, itu
| sudo tee
adalah cara kanonik, kadang-kadang sed (di sini dengan asumsi GNUsed
) dapat bekerja:-i
memodifikasi file di tempat.1i
berarti menyisipkan sebelum baris 1.$a
berarti menambahkan setelah baris terakhir.Atau salin ke xclipboard:
sumber
sed -i
tidak benar-benar memodifikasi file di tempat - itu membuat file sementara dan mengganti nama saat keluar. Jadi Anda tidak akan dapat melakukan sesuatu sepertitail -f ...
pada file asli dan melihat output menggunakansed -i ...
saat pipa sedang berjalan-i creates a new file of same name
atau ada sesuatu yang lebih kompak? Saya kira saya sukain place
, karena itu menjelaskani
. Manual gnu-sed menyebutnya di tempat juga dan bendera panjangnya--in-place
.Saya telah menendang-nebak ide-ide pikiran saya untuk masalah yang sama, dan muncul dengan solusi berikut:
sudo uncat
di manauncat
ada program yang membaca input standar dan menulisnya ke file bernama pada baris perintah, tapi saya belum menulisuncat
.sudocat
variansudoedit
yang belum saya tulis yang melakukan pembersihsudo cat
atausudo uncat
.atau trik kecil ini menggunakan
sudoedit
dengan EDITOR yang merupakan skrip shellyang dapat dipanggil sebagai salah satu
|sudo ./uncat file
atau| EDITOR=./uncat sudoedit
tetapi yang memiliki efek samping yang menarik.sumber
cat
mengambil daftar file ke con cat inate, oleh karena itu uncat harus mengambil daftar file ke un con cat inate. Itu harus menggunakan sihir untuk memutuskan berapa banyak untuk dimasukkan ke dalam setiap file. Nama alternatif termasukdog
,to-file
,redirect
.uncat
ketika saya punyatee
.tee
memiliki kelemahan sepele yang ia tulis stdin ke stdout - yang diremehkan sepele dengan mengarahkan stdout ke/dev/null
. Alternatif lain termasukdd of=/tmp/foo
(disebutkan dalam jawaban lain), yang menulis informasi status ke stderr, dancp /dev/stdin /tmp/foo
.Gunakan spons dari paket moreutils. Ini memiliki keuntungan bahwa ia tidak menulis ke stdout.
Gunakan opsi -a untuk menambahkan file daripada menimpanya.
sumber
/dev/null
jika itu masalahKesalahan berasal dari urutan shell melakukan sesuatu.
Pengalihan ditangani bahkan sebelum shell mengeksekusi
sudo
, dan karena itu dilakukan dengan izin dari pengguna yang saat ini Anda bekerja. Karena Anda tidak memiliki izin menulis untuk membuat / memotong target pengalihan, Anda mendapatkanpermission denied
kesalahan dari shell.Solusinya adalah untuk menjamin bahwa file keluaran dibuat di bawah identitas yang diberikan kepada Anda oleh
sudo
, misalnya dengantee
:sumber