Lorsque vous essayez de modifier un fichier sans avoir les droits d'écriture, vous obtenez une erreur:
> touch /tmp/foo && sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Sudoing n'aide pas, car il exécute la commande en tant que root, mais le shell gère la redirection de stdout et ouvre le fichier comme vous le faites quand même:
> sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Existe-t-il un moyen simple de rediriger stdout vers un fichier sur lequel vous n’avez pas l’autorisation d’écrire, en plus d’ouvrir un shell en tant que root et de manipuler le fichier de cette façon?
> sudo su
# echo test > /tmp/foo
shell
permissions
io-redirection
sudo
io
Michael Mrozek
la source
la source
chown
de changer de propriétaire; ce n'était qu'un exempleRéponses:
Oui, en utilisant
tee
. Ainsiecho test > /tmp/foo
devientVous pouvez aussi ajouter (
>>
)la source
echo test | sudo tee /tmp/foo > /dev/null
Pour remplacer le contenu du fichier par la sortie de
echo
(comme l'>
opérateur de redirection du shell).Pour écrire dans le fichier (au début, bien que vous puissiez utiliser
seek
pour générer des décalages différents) sans tronquer (comme l’1<>
opérateur Bourne Shell):Pour ajouter au fichier (comme
>>
), avec GNUdd
:Voir aussi GNU
dd
deconv=excl
fichier pour éviter un existant démolir (comme avecset -o noclobber
dans les coquilles POSIX) etconv=nocreat
le contraire (mise à jour uniquement un fichier existant).la source
echo test | sudo tee /tmp/foo >/dev/null
à supprimer la sortie.dd
n'est pas fiable pour cela, sauf si vous utilisez des options obscures réservées à GNUiflag=fullblock oflag=fullblock
, qui enlèvent toute l'élégance de cette réponse. Je vais rester avectee
.dd
peut être assez dangereux (sinon dire: dévastateur) si seulement une légère erreur a été commise. Donc, pour les nouveaux utilisateurs, je recommanderais plutôt latee
méthode sur la rive sûre.dd of=file
seul (sanscount
/skip
...), il est fiable.iflag=fullblock
n'est pas nécessaire car icidd
écrit en sortie ce qu'il a lu en entrée. Peu importe que ce ne soit pas des blocs complets.tee
est probablement le meilleur choix, mais selon votre situation, cela peut suffire:la source
eval
au lieu d'un simplesh -c
; -i, ce qui changera votre répertoire de travail; exécuter la commande entière en tant que root, ce qui pourrait changer son comportement ou présenter un risque inutile. pourquoi cela at-il déjà eu un vote positif?Bien que je sois d’accord, c’est
| sudo tee
la voie canonique, parfois sed (ici en supposant que GNUsed
) peut fonctionner:-i
modifie le fichier en place.1i
signifie insérer avant la ligne 1.$a
signifie ajouter après la dernière ligne.Ou copier sur xclipboard:
la source
sed -i
cela ne modifie pas réellement le fichier en place - il crée un fichier temporaire et le renomme à la sortie. Donc, vous ne pourrez pas faire quelque chose commetail -f ...
sur le fichier d'origine et voir la sortie en utilisantsed -i ...
pendant que le pipeline est en cours d'exécution-i creates a new file of same name
ou y a-t-il quelque chose de plus compact? Je suppose que j'aime bienin place
, parce que cela explique lai
. Le manpage appelle sed gnu- en place trop et long drapeau est--in-place
.J'avais des idées en tête à propos d'un problème similaire et j'ai proposé les solutions suivantes:
sudo uncat
oùuncat
est un programme qui lit l'entrée standard et l'écrit dans le fichier nommé sur la ligne de commande, mais je n'ai pasuncat
encore écrit .sudocat
la variante de cesudoedit
que je n'ai pas encore écrit qui fait un nettoyeursudo cat
ousudo uncat
.ou cette petite astuce de l'utilisation
sudoedit
avec un éditeur qui est un script shellqui peut être invoqué en tant que ou
|sudo ./uncat file
ou| EDITOR=./uncat sudoedit
mais qui a des effets secondaires intéressants.la source
cat
prend une liste de fichiers à con cat iner donc UNCAT devrait prendre une liste de fichiers à un con chat iner à. Il faudrait utiliser la magie pour décider combien mettre dans chaque fichier. Nom alternatif comprennentdog
,to-file
,redirect
.uncat
quand j'aitee
.tee
l’inconvénient trivial est qu’il écrit son stdin sur sa stdout - ce qui est atténué de manière triviale en redirigeant la stdout/dev/null
. D'autres alternatives incluentdd of=/tmp/foo
(mentionnées dans une autre réponse), qui écrit des informations d'état sur stderr, etcp /dev/stdin /tmp/foo
.Utilisez une éponge du paquet moreutils. Il a l'avantage de ne pas écrire sur stdout.
Utilisez l'option -a pour ajouter un fichier au lieu de l'écraser.
la source
/dev/null
s'il s'agissait d'un problèmeL'erreur provient de l'ordre dans lequel le shell fait les choses.
La redirection est gérée avant même que le shell ne s'exécute
sudo
. Elle est donc effectuée avec les autorisations de l'utilisateur avec lequel vous travaillez. Comme vous ne disposez pas des autorisations en écriture pour créer / tronquer la cible de la redirection, vous obtenez unepermission denied
erreur du shell.La solution consiste à garantir que le fichier de sortie est créé sous l'identité qui vous a été attribuée par
sudo
, par exemple, avectee
:la source