@Geekosaur'un açıkladığı gibi, kabuk komutu çalıştırmadan önce yönlendirmeyi yapar. Bunu yazdığınızda:
sudo foo >/some/file
Mevcut kabuk işleminiz, önce /some/fileyazmak için açmaya çalışan kendisinin bir kopyasını oluşturur , daha sonra başarılı olursa, o dosya tanımlayıcısını standart çıktısı yapar ve yalnızca başarılı olursa çalıştırılır sudo. Bu ilk adımda başarısız oluyor.
İzin veriliyorsa (sudoer yapılandırmaları genellikle kabukların çalıştırılmasını engeller), şöyle bir şey yapabilirsiniz:
sudo bash -c 'foo >/some/file'
Ama genel olarak | sudo teeyerine >ve | sudo tee -ayerine kullanmak iyi bir çözüm buluyorum >>. Bu, özellikle yeniden yönlendirme ihtiyacım olan tek nedeyse yararlıdır sudo; Sonuçta, gereksiz yere kök olarak çalışan süreçler, tam sudoolarak kaçınmak için yaratılan şeydir . Ve echokök olarak çalıştırmak çok aptalca.
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
> /dev/nullSonunda ekledim çünkü teeçıktısını hem adlandırılmış dosyaya hem de kendi standart çıktısına gönderiyor ve onu terminalimde görmeme gerek yok. ( teeKomut. Bu adı aldığı nerede fiziksel testlere boru hattında "T" konnektör gibi davranır) Ve (tek tırnak geçti '... '(çiftler yerine) "... "her şeyin değişmez ve ben bu yüzden) önüne ters eğik çizgi yoktu $in $arch. (Tırnak işaretleri veya ters eğik çizgi olmadan, muhtemelen mevcut olmayan $archkabuk parametresinin değeri ile değiştirilirdi arch, bu durumda $archhiçbir şeyle değiştirilir ve ortadan kaybolur.)
Böylece dosyalara root kullanarak yazmayı halleder sudo. Şimdi, bir kabuk betiğinde satırsonu içeren metinlerin çıktısını almanın yolları hakkında uzun bir araştırma. :)
BLUF için, dedikleri gibi, tercih ettiğim çözüm, yukarıdaki sudo teekomuta sadece bir buradaki belgeyi beslemek olurdu ; o zaman catya echoya printfda ya da başka herhangi bir komuta gerek yoktur . Tek tırnak işaretleri, sentinel giriş kısmına taşındı <<'EOF', ancak burada aynı etkiye sahipler: beden, gerçek metin olarak değerlendirildi, bu yüzden $archyalnız bırakıldı:
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch
EOF
Ama ben böyle yapsam da alternatifler var. Burda biraz var:
echoHer satıra bir tane yapıştırabilirsiniz , ancak hepsini bir alt kabukta gruplayabilirsiniz, böylece dosyaya yalnızca bir kez eklemeniz gerekir:
(echo '[archlinuxfr]'
echo 'Server = http://repo.archlinux.fr/$arch'
echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null
Eğer eklerseniz -eiçin echo(ve destekleri POSIX olmayan uzatma o bir kabuk kullanıyorsanız), kullanmakta dize doğrudan yeni satır gömebilirsiniz \n:
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Ancak yukarıda da söylediği gibi, bu POSIX tarafından belirtilen davranış değildir; Kabuğunuz sadece bir değişmez değeri ve -eardından bir dizi değişmez \ns içeren bir dizeyi yankılayabilir . Bunu yapmanın POSIX yolu, printfyerine kullanmaktır echo; otomatik olarak argümanına yaptığı gibi davranır echo -e, ancak otomatik olarak sonuna bir satırsonu eklemez, bu yüzden \noraya da bir fazladan yapıştırmanız gerekir :
printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n \n' |
sudo tee -a /etc/pacman.conf >/dev/null
Bu çözümlerden herhangi birinde, bir argüman dizesi olarak komutun aldığı şey iki karakterli diziyi içerir \nve bunu yeni satıra çevirmek komut programının kendisine (içindeki kod printfveya echo) bağlıdır. Birçok modern kabukları, sen ANSI tırnak kullanma seçeneği $'... 'gibi dizileri çevirmek hangi \niçine literal komut programı hiç dize görmeden satırbaşıyla. Bu, bu tür dizelerin herhangi bir komutla çalıştığı anlamına gelir, düz eski -e-siz dahil echo:
echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Ancak, daha taşınabilir olsalar da echo -e, ANSI alıntıları hala POSIX olmayan bir uzantıdır.
Ve yine, bunların hepsi seçenek olsa da, tee <<EOFyukarıdaki düz çözümü tercih ediyorum .