sudo echo "etwas" >> / etc / privilegedFile funktioniert nicht

586

Dies ist eine ziemlich einfache Frage zu Sudo-Berechtigungen unter Linux, zumindest scheint es so, als ob es so sein sollte.

Es gibt viele Fälle, in denen ich nur etwas an /etc/hostseine ähnliche Datei anhängen möchte, dies aber am Ende nicht kann, weil beides >und >>auch mit root nicht erlaubt sind.

Gibt es eine Möglichkeit, diese Arbeit zu machen, ohne zu suoder sudo suin root zu müssen?

David
quelle

Antworten:

855

Verwenden Sie tee --appendoder tee -a.

echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list

Vermeiden Sie Anführungszeichen in Anführungszeichen.

Um zu vermeiden, dass Daten zurück an die Konsole gedruckt werden, leiten Sie die Ausgabe nach / dev / null um.

echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list > /dev/null

Denken Sie an die ( -a/ --append) Flagge! Funktioniert einfach teeso >und überschreibt Ihre Datei. tee -afunktioniert wie >>und wird am Ende der Datei schreiben.

Yoo
quelle
3
Ich bevorzuge diesen absolut. Es ist einfach das einfachste (und es hat mich über Tee informiert, was auch in anderen Szenarien nützlich ist).
Joachim Sauer
5
Genau. Scheint ordentlicher zu sein, als auch einen neuen Sh zu starten, besonders wenn es darum geht, Dinge mit der Umwelt usw. zu tun.
Sam Brightman
39
Eine wichtige Sache zu beachten: Vergessen Sie NIEMALS das -a! Stellen Sie sich vor, was ein echo 'tmpfs /tmp tmpfs defaults 0 0' | sudo tee /etc/fstabtun würde
mic_e
21
Unter OS X sollte dies tee -aanstelle von sein tee --append.
Stricken
26
Für diejenigen, die nicht verstehen, was @mic_e gesagt hat: Ohne das-a--append Flag ( ) würde der Befehl die gesamte Datei mit der angegebenen Zeichenfolge überschreiben, anstatt sie an das Ende anzuhängen .
Totymedli
314

Das Problem ist, dass die Shell eine Umleitung ausgibt, nicht Sudo oder Echo. Dies geschieht also als Ihr normaler Benutzer.

Versuchen Sie das folgende Code-Snippet:

sudo sh -c "echo 'something' >> /etc/privilegedfile"
Matt P.
quelle
Was sind "Sudo-Berechtigungsgrenzen"? Es ist nur die Shell, die den Umleitungsoperator aus offensichtlichen Gründen mit höherer Priorität als ein Befehl analysiert
Vinko Vrsalovic
1
Abhängig von Ihrem shkann Echo Escape-Sequenzen wie \tin einfachen Anführungszeichen interpretieren . Sie könnten printf %s 'something'stattdessen verwenden.
Lri
Die Verwendung von Tee ist beliebter und kompatibler mit neueren Distributionen.
Eduardo B.
1
Dies ist der einzige, der wie er ist als SSH-Befehl funktioniert, der auf einem Remote-Knoten ausgeführt werden kann.
Duncan Lock
Ich stimme anderen Beiträgen hier zu. Dies verwendet eine Shell und nur eine Shell, sodass hier kein anderes Programm wie tee erforderlich ist. Ja, ich weiß, dass Tee bereits installiert ist, aber vielleicht nicht abhängig davon, welche Mikrodistribution Sie wie Bare Bones Alpine verwenden. Ich finde es gut, dass Sie auch eine Shell-Option haben: sudo /bin/bash -c "echo 'fs.inotify.max_user_watches = 524288' > /etc/sysctl.d/60-golang-inotify.conf"zum Beispiel.
Ligemer
35

Das Problem ist, dass Ihre Shell die Umleitung übernimmt. Es wird versucht, die Datei mit Ihren Berechtigungen zu öffnen, nicht mit denen des Prozesses, den Sie unter sudo ausführen.

Verwenden Sie vielleicht so etwas:

sudo sh -c "echo 'something' >> /etc/privilegedFile"
Vorfall
quelle
@GordonSun Dies liegt daran, dass sudodie Umgebung (aus Sicherheitsgründen) nicht an den Unterprozess weitergegeben wird. Sie können sudo -Ediese Einschränkung verwenden , um sie zu umgehen.
Arielf
1
@ GordonSun ja, ich verstehe nicht, warum du diese Aussage immer wieder wiederholst! Wenn Sie das tun sudo sh -c "echo 'something' >> $FILENAME", mit doppelten Anführungszeichen, dies wird funktionieren - die Variablensubstitution durch die äußere Schale getan, nicht die sudoed Shell.
Nadav Har'El
19
sudo sh -c "echo 127.0.0.1 localhost >> /etc/hosts"
Vinko Vrsalovic
quelle
13

Tun

sudo sh -c "echo >> somefile"

sollte arbeiten. Das Problem ist, dass> und >> von Ihrer Shell behandelt werden, nicht vom Befehl "sudoed". Die Berechtigungen sind also Ihre und nicht die des Benutzers, in den Sie "sudoing".

agnul
quelle
9

Für Neugierige möchte ich darauf hinweisen, dass Sie auch einen Heredoc (für große Blöcke) zitieren können:

sudo bash -c "cat <<EOIPFW >> /etc/ipfw.conf
<?xml version=\"1.0\" encoding=\"UTF-8\"?>

<plist version=\"1.0\">
  <dict>
    <key>Label</key>
    <string>com.company.ipfw</string>
    <key>Program</key>
    <string>/sbin/ipfw</string>
    <key>ProgramArguments</key>
    <array>
      <string>/sbin/ipfw</string>
      <string>-q</string>
      <string>/etc/ipfw.conf</string>
    </array>
    <key>RunAtLoad</key>
    <true></true>
  </dict>
</plist>
EOIPFW"
msanford
quelle
1
Dies funktioniert hervorragend, außer dass die eingebetteten Anführungszeichen möglicherweise mit einem \
N Jones
Ganz richtig @NJones! Ich werde meine Antwort bearbeiten. (Beachten Sie jedoch, dass wenn Sie dies nicht tun, das interne entfernt wird, "aber der Befehl nicht fehlschlägt.)
msanford
8

In Bash können Sie teein Kombination mit verwenden > /dev/null, um stdout sauber zu halten.

 echo "# comment" |  sudo tee -a /etc/hosts > /dev/null
Vytenis Bivainis
quelle
4

Mit Yoo Antwort , setzen Sie diese in Ihre ~/.bashrc:

sudoe() {
    [[ "$#" -ne 2 ]] && echo "Usage: sudoe <text> <file>" && return 1
    echo "$1" | sudo tee --append "$2" > /dev/null
}

Jetzt kannst du rennen sudoe 'deb blah # blah' /etc/apt/sources.list


Bearbeiten:

Eine vollständigere Version, mit der Sie Eingaben in eine Datei leiten oder von dieser umleiten können. Sie enthält a -a Schalter zum Deaktivieren des Anhängens enthält (der standardmäßig aktiviert ist):

sudoe() {
  if ([[ "$1" == "-a" ]] || [[ "$1" == "--no-append" ]]); then
    shift &>/dev/null || local failed=1
  else
    local append="--append"
  fi

  while [[ $failed -ne 1 ]]; do
    if [[ -t 0 ]]; then
      text="$1"; shift &>/dev/null || break
    else
      text="$(cat <&0)"
    fi

    [[ -z "$1" ]] && break
    echo "$text" | sudo tee $append "$1" >/dev/null; return $?
  done

  echo "Usage: $0 [-a|--no-append] [text] <file>"; return 1
}
hololeap
quelle
2

Sie können auch spongeaus dem moreutilsPaket verwenden und müssen die Ausgabe nicht umleiten (dh kein teeRauschen zum Ausblenden):

echo 'Add this line' | sudo sponge -a privfile
Michael Goldshteyn
quelle
0

Durch die Nutzung sed -i mit $ a können Sie nach der letzten Zeile Text anhängen, der sowohl Variablen als auch Sonderzeichen enthält.

Beispiel: Hinzufügen von $ NEW_HOST mit $ NEW_IP zu / etc / hosts:

sudo sed -i "\$ a $NEW_IP\t\t$NEW_HOST.domain.local\t$NEW_HOST" /etc/hosts

sed Optionen erklärt:

  • -i für an Ort und Stelle
  • $ für die letzte Zeile
  • a zum Anhängen
Noam Manos
quelle
0

Echo 'Hallo Welt' | (sudo tee -a /etc/apt/sources.list)

Sudev Shetty
quelle
0

Wie wäre es mit:
Echo Text | sudo dd status = none of = privilegierte
Datei Ich möchte / proc / sys / net / ipv4 / tcp_rmem ändern.
Ich habe
Folgendes getan: sudo dd status = keine von = / proc / sys / net / ipv4 / tcp_rmem <<< "4096 131072 1024000"
eliminiert das Echo mit einem einzeiligen Dokument

Marcelo Pacheco
quelle
1
Bitte nehmen Sie sich einen Moment Zeit, um die Bearbeitungshilfe in der Hilfe durchzulesen . Die Formatierung beim Stapelüberlauf unterscheidet sich von anderen Websites.
Dharman
-1

Das hat bei mir funktioniert: ursprünglicher Befehl

echo "export CATALINA_HOME="/opt/tomcat9"" >> /etc/environment

Arbeitsbefehl

echo "export CATALINA_HOME="/opt/tomcat9"" |sudo tee /etc/environment
Fthi.a.Abadi
quelle
1
Sollte sein tee -a. Nur teewird die Datei überschreiben!
Codeforester
-6

Können Sie den Besitz der Datei ändern und sie nach cat >>dem Anhängen wieder ändern ?

sudo chown youruser /etc/hosts  
sudo cat /downloaded/hostsadditions >> /etc/hosts  
sudo chown root /etc/hosts  

So etwas für dich?

Pixistix
quelle
4
Chown ist ein destruktiver Befehl. Wenn ein Konfigurationsmanager dies zum Aktualisieren von / etc / hosts verwendet hat, gehört / etc / hosts plötzlich zum Konfigurationsbenutzer und nicht zum Root. Dies führt möglicherweise dazu, dass andere Prozesse keinen Zugriff auf / etc / hosts haben. Der springende Punkt bei sudo ist, zu vermeiden, dass etwas in root angemeldet ist, und über sudoers können auch weitere Einschränkungen auferlegt werden.
David