it-swarm-eu.dev

Jak lze použít Sudo k přesměrování výstupu na místo, ke kterému nemám oprávnění psát?

Dostal jsem Sudo přístup na jeden z našich vývojových boxů RedHat linux a zdá se, že se dost často dostávám k přesměrování výstupu na místo, k němuž normálně nemám přístup pro zápis.

Potíž je v tom, že tento nevyvratitelný příklad nefunguje:

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

Dostávám odpověď:

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

Jak to mohu dostat do práce?

760
Jonathan

Váš příkaz nefunguje, protože přesměrování provádí vaše prostředí Shell, které nemá oprávnění k zápisu do souboru /root/test.out. Přesměrování výstupu není provedeno Sudo.

Existuje několik řešení:

  • Spusťte prostředí Shell s nástrojem Sudo a přidejte k němu příkaz -c:

    Sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Vytvořte skript s příkazy a spusťte tento skript pomocí Sudo:

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

    Spustit Sudo ls.sh. Viz Steve Bennett's answer pokud nechcete vytvořit dočasný soubor.

  • Spusťte prostředí Shell s Sudo -s a poté spusťte příkazy:

    [[email protected]]$ Sudo -s
    [[email protected]]# ls -hal /root/ > /root/test.out
    [[email protected]]# ^D
    [[email protected]]$
    
  • Použijte Sudo tee (pokud musíte při volbě -c uniknout hodně):

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

    Přesměrování na /dev/null je nutné pro zastavení tee z výstupu na obrazovku. Do append namísto přepsání výstupního souboru (>>) použijte tee -a nebo tee --append (poslední je specifický pro GNU coreutils ).

Děkuji Jd , Adam J. Forster a Johnathan za druhé, třetí a čtvrté řešení.

1068
Cristian Ciupitu

Někdo zde právě navrhl sudoing tee:

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

To může být také použito k přesměrování libovolného příkazu do adresáře, ke kterému nemáte přístup. Funguje to proto, že program tee je v podstatě program "echo to file" a přesměrování na/dev/null má zastavit také výstup na obrazovku, aby zůstal stejný jako původní příklad uvedený výše.

89
Jonathan

Byl to trik, který jsem sám vymyslel

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

Problém je v tom, že příkaz příkaz dostane pod Sudo, ale redirection dostane pod vaším uživatelem. To je děláno Shell a tam je velmi málo můžete udělat.

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

Obvyklé způsoby, jak to obejít, jsou:

  • Zabalte příkazy ve skriptu, který voláte pod Sudo.

    Pokud se změní příkazy a/nebo soubor protokolu, můžete skript Provést jako argumenty. Například:

    Sudo log_script command /log/file.txt
    
  • Zavolat Shell a předat příkazový řádek jako parametr -c

    To je užitečné zejména pro jednorázové složené příkazy. Například:

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

Ještě další variace na téma:

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

Nebo samozřejmě:

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

Mají (malou) výhodu, že nemusíte pamatovat žádné argumenty na Sudo nebo sh/bash

19
Steve Bennett

Vysvětlení trochu o tom, proč je vhodnější volba tee

Za předpokladu, že máte příslušné oprávnění k provedení příkazu, který vytvoří výstup, pokud připojíte výstup svého příkazu k odpališti, musíte pouze zvýšit práva na odpaliště od společnosti Sudo a přenést tee k zápisu (nebo připojit) k danému souboru.

v příkladu uvedeném v otázce, která by znamenala:

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

pro několik praktických příkladů:

# 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

V každém z těchto příkladů berete výstup nepovoleného příkazu a zapisujete do souboru, který je obvykle zapisovatelný pouze rootem, což je původ vaší otázky.

Je to dobrý způsob, jak to udělat, protože příkaz, který generuje výstup, není prováděn se zvýšenými oprávněními. Nezdá se, že by na tom záleželo s echo, ale když je zdrojový skript skriptem, kterému nedůvěřujete, je to zásadní.

Všimněte si, že můžete použít volbu -a, chcete-li přiřadit append (jako >>) k cílovému souboru spíše než přepsat (jako >).

18
jg3

Udělejte Sudovi běh Shell, jako je tento:

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

Způsob, jakým bych se v této záležitosti zabýval, je následující:

Pokud potřebujete soubor zapsat/nahradit:

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

Pokud chcete soubor přidat:

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

Co takhle napsat scénář?

Název souboru: myscript

#!/bin/sh

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

# end script

Potom spusťte skript pomocí Sudo:

Sudo ./myscript
5
Jd

Udělal bych to takto:

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

Kdykoliv musím něco takového udělat, stávám se rootem:

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

Asi to není nejlepší způsob, ale funguje to.

3
Adam J. Forster

Nechci porazit mrtvého koně, ale je zde příliš mnoho odpovědí, které používají tee, což znamená, že musíte přesměrovat stdout na /dev/null, pokud nechcete na obrazovce vidět kopii. Jednodušším řešením je použít cat takto:

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

Všimněte si, jak je přesměrování vloženo do uvozovek tak, aby bylo vyhodnoceno Shellem spuštěným Sudo namísto toho, který je spuštěn.

3
haridsv

To je založeno na odpovědi tee. Pro zjednodušení jsem napsal malý skript (říkám to suwrite) a dal ho do /usr/local/bin/ s povolením +x:

#! /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

Jak je ukázáno v kóduUSEv kódu, vše, co musíte udělat, je napojit výstup do tohoto skriptu následovaný požadovaným superuživatelem přístupným názvem a v případě potřeby vás bude automaticky vyzývat k zadání hesla. zahrnuje Sudo).

echo test | suwrite /root/test.txt

Vzhledem k tomu, že se jedná o jednoduchý wrapper pro tee, bude také přijímat možnost -a tee, která bude připojena, a také podporuje zápis do více souborů současně.

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

To také má nějakou zjednodušující ochranu proti psaní /dev/ zařízení, která byla znepokojení zmínil se v jednom z komentářů na této stránce.

2
jamadagni

Možná jste dostali Sudo přístup pouze k některým programům/cestám? Pak neexistuje žádný způsob, jak dělat to, co chcete. (ledaže bys to nějak zasekl)

Pokud tomu tak není, můžete napsat bash skript:

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

Lis ctrl + d :

chmod a+x myscript.sh
Sudo myscript.sh

Doufám, že to pomůže.

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