it-swarm-tr.com

Sudo'yu, çıktı yazma iznim olmayan bir konuma yönlendirmek için nasıl kullanırım?

Geliştirme RedHat linux kutularından birine Sudo erişimi verildi ve çıktılarımı normalde yazma erişimi olmayan bir yere yönlendirmek için sık sık kendimi bulmaya başladım.

Sorun şu, bu tartışılan örnek işe yaramıyor:

Sudo ls -hal /root/ > /root/test.out

Ben sadece yanıtı alıyorum:

-bash: /root/test.out: Permission denied

Bunun işe yaramasını nasıl sağlayabilirim?

760
Jonathan

Yeniden yönlendirme, /root/test.out dizinine yazma izni olmayan Shell'iniz tarafından gerçekleştirildiği için komutunuz çalışmıyor. Çıktının yeniden yönlendirilmesi Sudo tarafından gerçekleştirilmez .

Birden fazla çözüm var:

  • Sudo'lu bir Shell çalıştırın ve -c seçeneğini kullanarak ona komutu verin:

    Sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Komutlarınızla bir komut dosyası oluşturun ve bu komut dosyasını Sudo ile çalıştırın:

    #!/bin/sh
    ls -hal /root/ > /root/test.out
    

    Sudo ls.sh komutunu çalıştırın. Geçici bir dosya oluşturmak istemiyorsanız Steve Bennett'in yanıtına bakın.

  • Sudo -s ile bir Shell başlatın, sonra komutlarınızı çalıştırın:

    [[email protected]]$ Sudo -s
    [[email protected]]# ls -hal /root/ > /root/test.out
    [[email protected]]# ^D
    [[email protected]]$
    
  • Sudo tee kullanın (-c seçeneğini kullanırken çok fazla kaçmak zorundaysanız):

    Sudo ls -hal /root/ | Sudo tee /root/test.out > /dev/null
    

    /dev/null yönlendirmesine, tee ekranının gösterilmesini engellemek için gereklidir. Çıkış dosyasının üzerine yazmak yerine eklemek (>>), tee -a veya tee --append (sonuncusu GNU coreutils ).

İkinci, üçüncü ve dördüncü çözümler için Jd , Adam J. Forster ve Johnathan 'a teşekkürler.

1134
Cristian Ciupitu

Burada birileri az önce sudo tişörtünü önerdi:

Sudo ls -hal /root/ | Sudo tee /root/test.out > /dev/null

Bu, herhangi bir komutu, erişiminiz olmayan bir dizine yönlendirmek için de kullanılabilir. Bu, tee programının etkili bir şekilde "bir dosyaya yankılanması" programı olduğu ve/dev/null yönüne yönlendirmesinin, yukarıdaki orijinal örnekle aynı olmasını sağlamak için ekrana çıkmasını engellemesidir.

89
Jonathan

Kendimi anladığım bir hile

Sudo ls -hal /root/ | Sudo dd of=/root/test.out
70
rhlee

Sorun, komutununSudo altında çalıştırılması, ancak yeniden yönlendirme kullanıcının altında çalıştırılmasıdır. Bu Shell tarafından yapılır ve bu konuda yapabileceğiniz çok az şey var.

Sudo command > /some/file.log
`-----v-----'`-------v-------'
   command       redirection

Bunu atlamanın normal yolları şunlardır:

  • Komutları Sudo altında çağırdığınız bir betiğe sarın.

    Komutlar ve/veya günlük dosyası değişirse, Script'in bunları argüman olarak kabul etmesini sağlayabilirsiniz. Örneğin:

    Sudo log_script command /log/file.txt
    
  • Bir Shell çağırın ve komut satırını -c ile bir parametre olarak iletin

    Bu özellikle bir off-off komutları için kullanışlıdır.

    Sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
    
41
dsm

Temadaki başka bir varyasyon:

Sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF

Veya elbette:

echo 'ls -hal /root/ > /root/test.out' | Sudo bash

Sudo veya sh/bash ile ilgili herhangi bir argümanı hatırlamanız gerekmeyen (küçük) avantajları vardır.

19
Steve Bennett

Tee seçeneğinin neden tercih edildiğine dair biraz netleştirme

Çıktıyı oluşturan komutu yürütmek için uygun izniniz olduğunu varsayarsak, komutunuzun çıktısını tişörte aktarırsanız, yalnızca tee'nin ayrıcalıklarını Sudo ile yükseltmeniz ve söz konusu dosyayı yazmak (veya eklemek) için doğrudan tee'yi yükseltmeniz gerekir.

soruda verilen örnekte şu anlama gelir:

ls -hal /root/ | Sudo tee /root/test.out

birkaç daha pratik örnek için:

# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | Sudo tee -a /etc/hosts

# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | Sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4

Bu örneklerin her birinde, ayrıcalıklı olmayan bir komutun çıktısını alıyor ve sorunuzun Kökeni olan yalnızca kök tarafından yazılabilen bir dosyaya yazıyorsunuz.

Bu şekilde yapmak iyi bir fikirdir, çünkü çıktıyı üreten komut, yüksek ayrıcalıklarla yürütülmez. Burada echo ile önemli görünmüyor, ancak source komutu tamamen güvenmediğiniz bir betik olduğunda, çok önemlidir.

-A seçeneğini, üzerine yazmak yerine hedef dosyaya eklemek için (örneğin, >>) eklemek için -a seçeneğini kullanabilirsiniz (> gibi).

18
jg3

Sudo'nun bir Shell çalıştırmasını sağlayın, şunun gibi:

Sudo sh -c "echo foo > ~root/out"
15
Penfold

Bu konuyla ilgili benim giderim:

Dosyayı yazmanız/değiştirmeniz gerekirse:

echo "some text" | Sudo tee /path/to/file

Dosyaya eklemeniz gerekirse:

echo "some text" | Sudo tee -a /path/to/file
8
Nikola Petkanski

Senaryo yazmaya ne dersin?

Dosya adı: myscript

#!/bin/sh

/bin/ls -lah /root > /root/test.out

# end script

Sonra betiği çalıştırmak için Sudo kullanın:

Sudo ./myscript
5
Jd

Bu şekilde yapardım:

Sudo su -c 'ls -hal /root/ > /root/test.out'
4
fardjad

Ne zaman böyle bir şey yapmam gerektiğinde, sadece kök oluyorum:

# Sudo -s
# ls -hal /root/ > /root/test.out
# exit

Muhtemelen en iyi yol değil, ama işe yarıyor.

3
Adam J. Forster

Ölü bir atı atmak istemem, ama burada tee kullanan çok fazla cevap var, bu da ekranda bir kopyasını görmek istemediğiniz sürece stdout/dev/null' a yönlendirmeniz gerektiği anlamına gelir. Daha basit bir çözüm, şunun gibi cat işlevini kullanmaktır:

Sudo ls -hal /root/ | Sudo bash -c "cat > /root/test.out"

Yönlendirmenin tırnak içine nasıl alındığına dikkat edin, böylece onu çalıştıran yerine Sudo tarafından başlatılan bir Shell tarafından değerlendirilir.

3
haridsv

Bu tee içeren cevaba dayanmaktadır. İşleri kolaylaştırmak için küçük bir senaryo yazdım (suwrite olarak adlandırıyorum) ve /usr/local/bin/ izniyle +x içine yazdım:

#! /bin/sh
if [ $# = 0 ] ; then
    echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
    exit 1
fi
for arg in "[email protected]" ; do
    if [ ${arg#/dev/} != ${arg} ] ; then
        echo "Found dangerous argument ‘$arg’. Will exit."
        exit 2
    fi
done
Sudo tee "[email protected]" > /dev/null

KULLANIMIkodunda gösterildiği gibi, tek yapmanız gereken çıktıyı bu betiğe yönlendirmek ve ardından istediğiniz kullanıcı tarafından erişilebilir dosya adını izlemektir. Sudo içerir).

echo test | suwrite /root/test.txt

Bunun tee için basit bir sarıcı olduğundan, aynı zamanda tee'nin -a seçeneğini de ekleyeceğini ve aynı anda birden fazla dosyaya yazmayı da destekleyeceğini unutmayın.

echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt

Ayrıca, bu sayfadaki yorumlardan birinde bahsedilen bir endişe olan /dev/ aygıtlarına yazmaya karşı bazı basit korumalara sahiptir.

2
jamadagni

Belki size sadece bazı programlara/yollara Sudo erişimi verilmiştir? O zaman istediğini yapmanın bir yolu yok. (bir şekilde kesmeyeceksen)

Durum böyle değilse bash betiğini yazabilirsiniz:

cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out 

Basın ctrl + d :

chmod a+x myscript.sh
Sudo myscript.sh

Umarım yardım eder.

1
user15453
Sudo at now  
at> echo test > /tmp/test.out  
at> <EOT>  
job 1 at Thu Sep 21 10:49:00 2017  
0
user8648126