Saya mencoba untuk mengotomatiskan penambahan sumber repositori di file pacman.conf arch saya tetapi menggunakan echo
perintah di skrip shell saya. Namun, gagal seperti ini: -
sudo echo "[archlinuxfr]" >> /etc/pacman.conf
sudo echo "Server = http://repo.archlinux.fr/\$arch" >> /etc/pacman.conf
sudo echo " " >> /etc/pacman.conf
-bash: /etc/pacman.conf: Permission denied
Jika saya mengubah /etc/pacman.conf secara manual menggunakan vim, dengan melakukan
sudo vim /etc/pacman.conf
dan berhenti menggunakan vim :wq
, semuanya berfungsi dengan baik dan pacman.conf saya telah diperbarui secara manual tanpa keluhan "Izin ditolak".
Mengapa demikian? Dan bagaimana cara saya sudo echo
bekerja? (btw, saya mencoba menggunakan sudo cat
juga tetapi gagal dengan Izin ditolak juga)
Jawaban:
Masalahnya adalah bahwa pengalihan sedang diproses oleh shell asli Anda, bukan oleh
sudo
. Kerang tidak mampu membaca pikiran dan tidak tahu bahwa hal khusus>>
itu dimaksudkan untuk itusudo
dan bukan untuk itu.Kamu butuh:
sudo)
sudo -s
(sehinggasudo
menggunakan shell untuk memproses pengalihan yang dikutip.)sumber
sudo -s
(2) echo "# test" >> /etc/pacman.conf bekerja. Tetapi apakah mungkin untuk mengeksekusi ini dalam satu baris?sudo -s 'echo "# test" >>/etc/pacman.conf'
adalah apa yang saya coba sampaikan kepada Anda.sudo -s 'echo "# test" >> /etc/pacman.conf' /bin/bash: echo "# test" >> /etc/pacman.conf: No such file or directory
itulah sebabnya saya kemudian mencoba proses manual 2 langkah.echo 'echo "# test" >> /etc/pacman.conf' | sudo -s
sudo
penonaktifan konfigurasi-s
? Visudo?Seperti yang dijelaskan @geekosaur, shell melakukan pengalihan sebelum menjalankan perintah. Saat Anda mengetik ini:
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 dieksekusisudo
. 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 perlukansudo
sejak awal; lagipula, menjalankan proses yang tidak perlu sebagai root adalah hal yangsudo
sebenarnya harus dihindari. Dan menjalankanecho
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 karenatee
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 shellarch
, 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 diperlukancat
atauecho
atauprintf
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
keecho
(dan Anda menggunakan shell yang mendukung ekstensi non-POSIX), Anda dapat menyematkan baris baru langsung ke dalam string menggunakan\n
:# NON-POSIX - NOT RECOMMENDED 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 menggunakanprintf
alih-alihecho
; itu secara otomatis memperlakukan argumennya sepertiecho -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 dalamprintf
atauecho
) 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
-kurangecho
: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.sumber
sudo bash -c 'foo >/some/file'
bekerja untuk saya di osx :-)cat <<EOF | sudo tee -a /some/file > /dev/null ...
cat
proses yang tidak relevan . :)http://www.innovationsts.com/blog/?p=2758
Karena petunjuknya tidak begitu jelas di atas, saya menggunakan petunjuk dari posting blog itu. Dengan contoh sehingga lebih mudah untuk melihat apa yang perlu Anda lakukan.
Perhatikan bahwa perintah kedua (perintah gzip) di pipeline yang menyebabkan error. Di situlah teknik kami menggunakan bash dengan opsi -c masuk.
Kita dapat melihat dari output perintah ls bahwa pembuatan file terkompresi berhasil.
Metode kedua mirip dengan yang pertama karena kami mengirimkan string perintah ke bash, tetapi kami melakukannya dalam pipeline melalui sudo.
sumber
sudo bash -c 'echo "[archlinuxfr]" >> /etc/pacman.conf'
sumber
LANGKAH 1 buat fungsi di file bash (
write_pacman.sh
)#!/bin/bash function write_pacman { tee -a /etc/pacman.conf > /dev/null << 'EOF' [archlinuxfr] Server = http://repo.archlinux.fr/\$arch EOF }
'EOF'
tidak akan menafsirkan$arch
variabel.File bash sumber STE2
$ source write_pacman.sh
LANGKAH 3 jalankan fungsi
sumber
tambahkan file (sudo cat):
tambahkan echo ke file (sudo echo):
echo <origin> | sudo tee -a <target-file>
(EXTRA) abaikan ouput:
echo >origin> | sudo tee -a <target-file> >/dev/null
sumber