it-swarm-eu.dev

Wie verwende ich Sudo, um die Ausgabe an einen Ort umzuleiten, an den ich nicht schreiben darf?

Ich habe Sudo-Zugriff auf eine unserer RedHat-Linux-Entwicklungsboxen erhalten, und es scheint, als müsste ich die Ausgabe häufig an einen Ort umleiten, auf den ich normalerweise keinen Schreibzugriff habe.

Das Problem ist, dass dieses erfundene Beispiel nicht funktioniert:

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

Ich erhalte gerade die Antwort:

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

Wie kann ich das zum Laufen bringen?

760
Jonathan

Ihr Befehl funktioniert nicht, da die Umleitung von Ihrer Shell ausgeführt wird, die nicht über die Berechtigung verfügt, in /root/test.out zu schreiben. Die Umleitung der Ausgabe wird von Sudo nicht durchgeführt .

Es gibt mehrere Lösungen:

  • Führen Sie eine Shell mit Sudo aus und geben Sie den Befehl mit der Option -c ein:

    Sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Erstellen Sie ein Skript mit Ihren Befehlen und führen Sie dieses Skript mit Sudo aus:

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

    Führen Sie Sudo ls.sh aus. Siehe Steve Bennetts Antwort , wenn Sie keine temporäre Datei erstellen möchten.

  • Starten Sie eine Shell mit Sudo -s und führen Sie dann Ihre Befehle aus:

    [[email protected]]$ Sudo -s
    [[email protected]]# ls -hal /root/ > /root/test.out
    [[email protected]]# ^D
    [[email protected]]$
    
  • Verwenden Sie Sudo tee (wenn Sie mit der Option -c viel flüchten müssen):

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

    Die Umleitung zu /dev/null wird benötigt, um die Ausgabe von tee auf dem Bildschirm zu stoppen. Verwenden Sie >> oder tee -a, um anzuhängen , anstatt die Ausgabedatei (tee --append) zu überschreiben (die letzte ist spezifisch für GNU coreutils ).

Vielen Dank an Jd , Adam J. Forster und Johnathan für die zweite, dritte und vierte Lösung.

1134

Jemand hier hat gerade sudoing tee vorgeschlagen:

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

Dies kann auch verwendet werden, um jeden Befehl in ein Verzeichnis umzuleiten, auf das Sie keinen Zugriff haben. Es funktioniert, weil das Abschlagprogramm tatsächlich ein "Echo an eine Datei" ist und die Umleitung zu/dev/null die Ausgabe auch auf dem Bildschirm anhält, damit sie mit dem oben beschriebenen ursprünglichen Beispiel übereinstimmt.

89
Jonathan

Ein Trick, den ich selbst herausgefunden habe

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

Das Problem ist, dass der Befehl command unter Sudo ausgeführt wird, die Umleitung jedoch unter Ihrem Benutzer ausgeführt wird. Dies wird von der Shell erledigt, und Sie können wenig dagegen tun.

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

Die üblichen Möglichkeiten, dies zu umgehen, sind:

  • Wickeln Sie die Befehle in ein Skript ein, das Sie unter Sudo aufrufen.

    Wenn sich die Befehle und/oder die Protokolldatei ändern, können Sie das Skript Als Argumente verwenden. Zum Beispiel:

    Sudo log_script command /log/file.txt
    
  • Rufen Sie eine Shell auf und übergeben Sie die Befehlszeile mit -c als Parameter.

    Dies ist besonders nützlich für einmalige zusammengesetzte Befehle . Zum Beispiel:

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

Noch eine Variation des Themas:

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

Oder natürlich:

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

Sie haben den (winzigen) Vorteil, dass Sie sich keine Argumente für Sudo oder sh/bash merken müssen.

19
Steve Bennett

Ein wenig klären, warum die Abschlagoption vorzuziehen ist

Angenommen, Sie verfügen über die entsprechende Berechtigung zum Ausführen des Befehls, der die Ausgabe erstellt. Wenn Sie die Ausgabe Ihres Befehls an tee weiterleiten, müssen Sie lediglich die Privilegien von tee mit Sudo und das direkte tee erhöhen, um an die betreffende Datei zu schreiben (oder anzuhängen).

in dem in der Frage angegebenen Beispiel würde das bedeuten:

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

für ein paar mehr praktische Beispiele:

# 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

In jedem dieser Beispiele übernehmen Sie die Ausgabe eines nicht privilegierten Befehls und schreiben in eine Datei, die normalerweise nur von root beschrieben werden kann. Dies ist der Ursprung Ihrer Frage.

Dies ist eine gute Idee, da der Befehl, der die Ausgabe generiert, nicht mit erhöhten Rechten ausgeführt wird. Bei echo scheint es hier keine Rolle zu spielen, aber wenn der Quellbefehl ein Skript ist, dem Sie nicht vollständig vertrauen, ist dies von entscheidender Bedeutung.

Hinweis: Sie können die Option -a verwenden, um das Anhängen (wie >>) an die Zieldatei anzuhängen, anstatt sie zu überschreiben (wie >).

18
jg3

Lassen Sie Sudo eine Shell ausführen, wie folgt:

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

Die Art und Weise, wie ich dieses Problem angehen würde, ist:

Wenn Sie die Datei schreiben/ersetzen müssen:

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

Wenn Sie an die Datei anhängen müssen:

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

Wie wäre es, ein Skript zu schreiben?

Dateiname: Myscript

#!/bin/sh

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

# end script

Verwenden Sie dann Sudo, um das Skript auszuführen:

Sudo ./myscript
5
Jd

Ich würde es so machen:

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

Immer wenn ich so etwas tun muss, werde ich einfach root:

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

Es ist wahrscheinlich nicht der beste Weg, aber es funktioniert.

3
Adam J. Forster

Man sollte nicht ein totes Pferd schlagen, aber es gibt zu viele Antworten, die tee verwenden. Das bedeutet, dass Sie stdout zu /dev/null umleiten müssen, sofern Sie keine Kopie auf dem Bildschirm sehen möchten. Eine einfachere Lösung ist, cat wie folgt zu verwenden:

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

Beachten Sie, wie die Umleitung in Anführungszeichen gesetzt wird, damit sie von einer Shell ausgewertet wird, die von Sudo gestartet wird, anstatt von der Shell, auf der sie ausgeführt wird.

3
haridsv

Dies basiert auf der Antwort, die tee beinhaltet. Zur Vereinfachung habe ich ein kleines Skript geschrieben (ich nenne es suwrite) und füge es mit der /usr/local/bin/-Berechtigung in +x ein:

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

Wie im CodeUSAGEim Code gezeigt, müssen Sie nur die Ausgabe an dieses Skript weiterleiten, gefolgt von dem gewünschten, für den Superuser zugänglichen Dateinamen. Wenn dies erforderlich ist, werden Sie automatisch zur Eingabe Ihres Kennworts aufgefordert enthält Sudo).

echo test | suwrite /root/test.txt

Da dies ein einfacher Wrapper für tee ist, akzeptiert er die anhängige Option -a von Tee und unterstützt gleichzeitig das Schreiben in mehrere Dateien.

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

Es hat auch einen einfachen Schutz gegen das Schreiben auf /dev/-Geräte, was in einem Kommentar auf dieser Seite besorgt war.

2
jamadagni

Vielleicht haben Sie mit Sudo nur Zugriff auf einige Programme/Pfade? Dann gibt es keine Möglichkeit, das zu tun, was Sie wollen. (es sei denn, Sie werden es irgendwie hacken)

Wenn dies nicht der Fall ist, können Sie vielleicht ein Bash-Skript schreiben:

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

Drücken Sie ctrl + d :

chmod a+x myscript.sh
Sudo myscript.sh

Hoffe es hilft.

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