sudo echo "quelque chose" >> / etc / privilegedFile ne fonctionne pas


586

C'est une question assez simple, au moins il semble que cela devrait être, sur les autorisations sudo sous Linux.

Il y a de nombreuses fois où je veux simplement ajouter quelque chose /etc/hostsou un fichier similaire, mais je ne peux pas le faire car les deux >et >>ne sont pas autorisés, même avec root.

Existe-t-il un moyen de faire ce travail sans avoir à suou sudo suen root?

Réponses:


855

Utilisez tee --appendou tee -a.

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

Assurez-vous d'éviter les guillemets à l'intérieur des guillemets.

Pour éviter de réimprimer les données sur la console, redirigez la sortie vers / dev / null.

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

N'oubliez pas le drapeau ( -a/ --append)! Fonctionne teecomme >et écrasera votre fichier. tee -afonctionne comme >>et écrit à la fin du fichier.


3
Je préfère absolument celui-ci. C'est juste le plus simple (et il m'a appris le tee, qui est également utile dans d'autres scénarios).
Joachim Sauer, le

5
Je suis d'accord. Semble plus propre que de commencer un nouveau sh, surtout avec potentiellement de faire des choses avec l'environnement, etc.
Sam Brightman

39
Une chose importante à noter: N'oubliez JAMAIS le -a! Imaginez juste ce que echo 'tmpfs /tmp tmpfs defaults 0 0' | sudo tee /etc/fstabferait
mic_e

21
Sous OS X, cela devrait être tee -aau lieu de tee --append.
knite

26
Pour ceux qui ne comprennent pas ce que @mic_e a dit: sans l'-a--append indicateur ( ), la commande écraserait le fichier entier avec la chaîne donnée au lieu de l'ajouter à la fin.
totymedli

314

Le problème est que le shell produit une redirection, pas sudo ou echo, donc cela se fait en tant qu'utilisateur normal.

Essayez l'extrait de code suivant:

sudo sh -c "echo 'something' >> /etc/privilegedfile"

Que sont les «limites d'autorisation sudo»? C'est juste le shell qui analyse l'opérateur de redirection avec une priorité plus élevée qu'une commande pour des raisons évidentes
Vinko Vrsalovic

1
En fonction de votre sh, echo peut interpréter des séquences d'échappement comme à l' \tintérieur de guillemets simples. Vous pouvez utiliser à la printf %s 'something'place.
Lri

L'utilisation de tee est plus populaire et plus compatible avec les nouvelles distributions.
Eduardo B.

1
C'est la seule qui fonctionne telle quelle comme une commande SSH qui peut être exécutée sur un nœud distant.
Duncan Lock

Je suis d'accord avec d'autres articles ici. Cela utilise un shell et uniquement un shell, donc un autre programme comme tee n'est pas nécessaire ici. Oui, je sais que le tee est déjà installé, mais peut-être pas en fonction de la micro distro que vous utilisez comme les os nus alpins. J'aime que vous ayez aussi une option shell: sudo /bin/bash -c "echo 'fs.inotify.max_user_watches = 524288' > /etc/sysctl.d/60-golang-inotify.conf"par exemple.
Ligemer

35

Le problème est que c'est votre shell qui gère la redirection; il essaie d'ouvrir le fichier avec vos autorisations et non celles du processus que vous exécutez sous sudo.

Utilisez quelque chose comme ça, peut-être:

sudo sh -c "echo 'something' >> /etc/privilegedFile"

@GordonSun c'est parce que sudo(pour des raisons de sécurité) ne propage pas l'environnement au sous-processus. Vous pouvez utiliser sudo -Epour contourner cette restriction.
arielf

1
@GordonSun oui, je ne comprends pas pourquoi vous répétez cette déclaration! Si vous le faites sudo sh -c "echo 'something' >> $FILENAME", avec des guillemets doubles, ce sera travail - la substitution de variables est faite par l'enveloppe extérieure, et non la coquille sudoed.
Nadav Har'El


13

Faire

sudo sh -c "echo >> somefile"

devrait marcher. Le problème est que> et >> sont gérés par votre shell, pas par la commande "sudoed", donc les permissions sont les vôtres, pas celles de l'utilisateur dans lequel vous "sudoing".


9

Je note, pour les curieux, que vous pouvez également citer un hérédoc (pour les gros blocs):

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"

1
Cela fonctionne très bien, sauf que les guillemets intégrés peuvent devoir être échappés avec un \
N Jones

Tout à fait @NJones! Je vais modifier ma réponse. (Notez, cependant, que cela ne supprime pas l'interne "mais ne provoque pas l'échec de la commande.)
msanford

8

En bash, vous pouvez utiliser teeen combinaison avec > /dev/nullpour garder stdout propre.

 echo "# comment" |  sudo tee -a /etc/hosts > /dev/null

4

En utilisant la réponse de Yoo , mettez ceci dans votre ~/.bashrc:

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

Vous pouvez maintenant exécuter sudoe 'deb blah # blah' /etc/apt/sources.list


Éditer:

Une version plus complète qui vous permet de diriger l'entrée ou la redirection à partir d'un fichier et comprend un -acommutateur pour désactiver l'ajout (qui est activé par défaut):

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
}

2

Vous pouvez également utiliser à spongepartir du moreutilspackage et pas besoin de rediriger la sortie (c'est-à-dire, pas de teebruit à cacher):

echo 'Add this line' | sudo sponge -a privfile

0

En utilisant sed -i avec $ a , vous pouvez ajouter du texte, contenant à la fois des variables et des caractères spéciaux, après la dernière ligne.

Par exemple, en ajoutant $ NEW_HOST avec $ NEW_IP à / etc / hosts:

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

Options de sed expliquées:

  • -i pour en place
  • $ pour la dernière ligne
  • un pour ajouter


0

Que diriez-vous:
écho texte | sudo dd status = none of = privilegedfile
Je veux changer / proc / sys / net / ipv4 / tcp_rmem.
J'ai fait:
sudo dd status = aucun de = / proc / sys / net / ipv4 / tcp_rmem <<< "4096 131072 1024000"
élimine l'écho avec un document à une seule ligne


1
Veuillez prendre un moment pour lire l' aide à l' édition dans le centre d'aide . Le formatage sur Stack Overflow est différent de celui des autres sites.
Dharman

-1

Cela a fonctionné pour moi: commande originale

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

Commande de travail

echo "export CATALINA_HOME="/opt/tomcat9"" |sudo tee /etc/environment

1
Devrait l'être tee -a. Juste teeécraser le fichier!
codeforester

-6

Pouvez-vous modifier la propriété du fichier, puis le modifier à nouveau après avoir utilisé cat >>pour ajouter?

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

Quelque chose comme ce travail pour vous?


4
Chown est une commande destructrice à utiliser. Si un gestionnaire de configuration l'a utilisé pour mettre à jour / etc / hosts, soudainement / etc / hosts appartient à l'utilisateur de configuration et non à root. ce qui peut conduire à ce que d'autres processus n'aient pas accès à / etc / hosts. Le but de sudo est d'éviter d'avoir quelque chose connecté à root et via sudoers plus de restrictions peuvent également être empilées.
David
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.