Seperti yang dijelaskan @geekosaur, shell melakukan pengalihan sebelum menjalankan perintah. Saat Anda mengetik ini:
sudo foo >/some/file
Proses shell Anda saat ini membuat salinannya sendiri yang pertama kali mencoba dibuka /some/file
untuk penulisan, kemudian jika berhasil, deskriptor file tersebut akan menjadi keluaran standarnya, dan hanya jika berhasil, ia akan dieksekusi sudo
. Ini gagal pada langkah pertama.
Jika Anda diizinkan (konfigurasi sudoer sering menghalangi menjalankan shell), Anda dapat melakukan sesuatu seperti ini:
sudo bash -c 'foo >/some/file'
Tapi saya menemukan solusi yang baik secara umum adalah dengan menggunakan | sudo tee
bukannya >
dan | sudo tee -a
bukan >>
. Itu sangat berguna jika pengalihan adalah satu-satunya alasan yang saya perlukan sudo
sejak awal; lagipula, menjalankan proses yang tidak perlu sebagai root adalah hal yang sudo
sebenarnya harus dihindari. Dan menjalankan echo
sebagai root itu konyol.
echo '[archlinuxfr]' | sudo tee -a /etc/pacman.conf >/dev/null
echo 'Server = http://repo.archlinux.fr/$arch' | sudo tee -a /etc/pacman.conf >/dev/null
echo ' ' | sudo tee -a /etc/pacman.conf >/dev/null
Saya menambahkan > /dev/null
di akhir karena tee
mengirimkan output ke kedua file bernama dan output standar sendiri, dan saya tidak perlu melihatnya di terminal saya. ( tee
Perintah tersebut bertindak seperti konektor "T" dalam pipa fisik, yang merupakan asal namanya.) Dan saya beralih ke tanda kutip tunggal ( '
... '
) daripada tanda kutip ganda ( "
... "
) sehingga semuanya literal dan saya tidak perlu membuat garis miring terbalik di depan $
dalam $arch
. (Tanpa tanda kutip atau garis miring terbalik, $arch
akan digantikan oleh nilai parameter shell arch
, yang mungkin tidak ada, dalam hal $arch
ini diganti dengan tidak ada dan menghilang begitu saja.)
Sehingga menangani penulisan ke file sebagai root menggunakan sudo
. Sekarang untuk penyimpangan panjang tentang cara menghasilkan teks yang mengandung baris baru dalam skrip shell. :)
Untuk BLUF, seperti yang mereka katakan, solusi pilihan saya adalah dengan memasukkan dokumen di sini ke dalam sudo tee
perintah di atas ; maka tidak diperlukan cat
atau echo
atau printf
atau perintah lain sama sekali. Tanda kutip tunggal telah dipindahkan ke pengantar sentinel <<'EOF'
, tetapi memiliki efek yang sama di sana: isi diperlakukan sebagai teks literal, jadi $arch
dibiarkan sendiri:
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch
EOF
Tapi meski begitulah cara saya melakukannya, ada alternatif. Berikut ini beberapa di antaranya:
Anda dapat tetap menggunakan satu echo
per baris, tetapi kelompokkan semuanya menjadi subkulit, jadi Anda hanya perlu menambahkan ke file satu kali:
(echo '[archlinuxfr]'
echo 'Server = http://repo.archlinux.fr/$arch'
echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null
Jika Anda menambahkan -e
ke echo
(dan Anda menggunakan shell yang mendukung ekstensi non-POSIX), Anda dapat menyematkan baris baru langsung ke dalam string menggunakan \n
:
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Tetapi seperti yang dikatakan di atas, itu bukanlah perilaku yang ditentukan POSIX; shell Anda mungkin hanya menggemakan literal -e
diikuti dengan string dengan sekelompok literal \n
sebagai gantinya. Cara POSIX untuk melakukannya adalah dengan menggunakan printf
alih-alih echo
; itu secara otomatis memperlakukan argumennya seperti echo -e
halnya, tetapi tidak secara otomatis menambahkan baris baru di akhir, jadi Anda harus menempelkan tambahan di \n
sana juga:
printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n \n' |
sudo tee -a /etc/pacman.conf >/dev/null
Dengan salah satu solusi tersebut, apa yang didapat perintah sebagai string argumen berisi urutan dua karakter \n
, dan terserah pada program perintah itu sendiri (kode di dalam printf
atau echo
) untuk menerjemahkannya ke dalam baris baru. Di banyak shell modern, Anda memiliki opsi untuk menggunakan tanda kutip ANSI $'
... '
, yang akan menerjemahkan urutan seperti \n
ke dalam baris baru literal sebelum program perintah melihat string tersebut. Itu berarti string seperti bekerja dengan perintah apapun, termasuk tua polos -e
-kurang echo
:
echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Namun, meskipun lebih portabel daripada echo -e
, kutipan ANSI masih merupakan ekstensi non-POSIX.
Dan lagi, sementara itu semua adalah opsi, saya lebih suka tee <<EOF
solusi langsung di atas.