web-dev-qa-db-fra.com

Redirection de stdout dans un fichier que vous n'avez pas la permission d'écriture sur

Lorsque vous essayez de modifier un fichier sans avoir reçu des autorisations d'écriture, vous obtenez une erreur:

> touch /tmp/foo && Sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo

Le sudotage n'aide pas, car il exécute la commande en tant que root, mais la coquille traite la redirection de stdout et ouvre le fichier comme vous de toute façon:

> Sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo

Existe-t-il un moyen facile de rediriger Stdout dans un fichier que vous n'avez pas la permission d'écrire à, en plus d'ouvrir une coquille en tant que root et de manipuler le fichier de cette façon?

> Sudo su
# echo test > /tmp/foo
115
Michael Mrozek

Oui, en utilisant tee. Donc echo test > /tmp/foo devient

echo test | Sudo tee /tmp/foo

Vous pouvez également ajouter (>>)

echo test | Sudo tee -a /tmp/foo
119
Gert

Pour remplacer le contenu du fichier avec la sortie de echo (comme le > Opérateur de redirection de Shell).

echo test | Sudo dd of=/tmp/foo

Écrire dans le fichier (au début, bien que vous puissiez utiliser seek pour produire à différents décalages) sans tronquer (comme le 1<> Opérateur de shell de Bourne):

echo test | Sudo dd of=/tmp/foo conv=notrunc

Ajouter au fichier (comme >>), avec GNU dd:

echo test | Sudo dd of=/tmp/foo oflag=append conv=notrunc

Voir aussi GNU dd 's conv=excl Pour éviter d'encombrer un fichier existant (comme avec set -o noclobber dans les coquilles de POSIX) et conv=nocreat Pour le contraire (mettre à jour uniquement un fichier existant).

27
Chris Jepeway

tee est probablement le meilleur choix, mais en fonction de votre situation, quelque chose comme cela peut suffire:

Sudo sh -c 'echo test > /tmp/foo'
14
phunehehe

Pendant que je suis d'accord, que | Sudo tee est la voie canonique, parfois sed (ici en supposant GNU sed) peut fonctionner:

cat sudotest 
line 1

Sudo sed -i '1iitest' sudotest && cat sudotest 
itest
line 1

Sudo sed -i '$aatest' sudotest && cat sudotest 
itest
line 1
atest

-i modifie le fichier en place. 1i signifie insert Avant la ligne 1. $a signifie Ajouter Après la dernière ligne.

Ou copier sur xcliPboard:

somecommand | xclip
Sudo gedit sudotest
move cursor to desired place, click middle mouse button to insert, save
5
user unknown

Je me suis lancé dans le dos de mes idées d'esprit pour un problème similaire et j'ai proposé les solutions suivantes:

  • Sudo uncatuncat est un programme qui lit l'entrée standard et l'écrit au fichier nommé sur la ligne de commande, mais je n'ai pas encore écrit uncat.

  • sudocat la variante de sudoedit que je n'ai pas encore écrit qui fait un nettoyant Sudo cat ou Sudo uncat.

  • ou ce petit truc d'utilisation sudoedit avec un éditeur qui est un script shell

    #!/bin/sh
    # uncat
    cat > "$1"
    

    qui peut être invoqué comme étant |Sudo ./uncat file ou | EDITOR=./uncat sudoedit Mais cela a des effets secondaires intéressants.

2
hildred

Utilisez l'éponge à partir du paquet de plus. Il a l'avantage de ne pas écrire sur stdout.

echo test | Sudo sponge /tmp/foo

Utilisez l'option -A pour ajouter à un fichier au lieu de l'écraser.

1
Hontvári Levente

L'erreur vient de l'ordre dans lequel la coquille fait des choses.

La redirection est traitée avant que la coque s'exécute même Sudo et se déroule donc avec les autorisations de l'utilisateur que vous travaillez actuellement. Puisque vous n'avez pas d'autorisations d'écriture pour créer/tronquer la cible de la redirection, vous obtenez un permission denied erreur de la coquille.

La solution consiste à garantir que le fichier de sortie est créé sous l'identité donnée à vous par Sudo, par exemple. avec tee:

$ generate_output | Sudo tee target_file
0
Kusalananda