Par exemple, si je veux créer un fichier et saisir du texte sur une ligne, je peux rediriger la sortie dans un fichier en utilisant le >
opérateur :
echo "something" > /path/foobar
mais si je n'ai pas accès au dossier /path/
et j'ai besoin de privilèges sudo, comment puis-je obtenir cette même commande en tant qu'utilisateur normal avec des droits sudo ?
J'ai essayé
sudo echo "something" > /path/foobar
mais cela ne fonctionne pas, car le sudo ne compte que pour le edit
mais pas pour la partie droite
du >
Bien sûr, je pouvais devenir root avant avec sudo su
ou utilisez tee
à la place :
echo "something" | sudo tee /path/foobar
Mais je voudrais trouver une solution où je peux travailler avec la dernière ligne en remplacement via
sudo !!
N'y a-t-il pas un moyen de "recycler" la dernière ligne et d'ajouter simplement sudo
devant ?
Réponse acceptée :
Vous ne pouvez pas simplement coller sudo
devant une commande shell, vous devez invoquer un shell pour évaluer à nouveau cette commande (faire des choses comme développer des variables, ouvrir des fichiers pour les opérateurs de redirection, etc.). C'est donc
sudo bash -c !!
sauf que cela ne fonctionne pas tout à fait, car !!
interpole le texte de la commande précédente, les caractères spéciaux et tout. Vous devez récupérer le texte de la commande sous forme de chaîne et le transmettre en tant qu'argument à sh
. Heureusement, le fc
de bash builtin vous permet de faire cela¹.
sudo bash -c "$(fc -ln -1)"
Ou même, pour être sûr d'invoquer la même version de bash en cours d'exécution :
sudo "$BASH" -c "$(fc -ln -1)"
Notez que puisque la commande est exécutée dans un processus shell séparé, elle hérite des variables d'environnement (uniquement celles que sudo
préserve, esprit), mais pas les variables internes du shell. Options du shell (par exemple, kshglob
) et les autres paramètres commenceront à partir de la valeur par défaut.
La même commande² fonctionne dans zsh et ksh, bien que ATT ksh93 nécessite à la fois le first
et last
numéro à transmettre à fc
³ (qui fonctionne aussi dans bash, zsh et pdksh/mksh) :
sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"
Utiliser $0
désigner l'exécutable du shell en cours d'exécution ne fonctionne que si le shell a été appelé via le $PATH et que le $PATH n'a pas changé, ou via un chemin absolu.
Voici une autre méthode en zsh qui est un peu plus claire mais plus longue :
sudo zsh -c $history[$[HISTCMD-1]]
Un dernier mot d'avertissement :sudo
est pour les commandes potentiellement dangereuses. Ne le rendez pas trop facile à utiliser !
¹ Il y a des espaces supplémentaires au début et la substitution de commande supprime les nouvelles lignes à la fin, mais la syntaxe du shell ne s'en soucie pas.
² Je ne pense pas que zsh ou ksh aient quelque chose comme le $BASH
de bash; $0
ne fonctionne que lorsqu'il s'agit d'un chemin absolu ou lorsqu'il ne contient pas de barre oblique et que le chemin de recherche de la commande n'a pas changé.
³ fc
est un alias pour hist
en ATT ksh mais c'est tout aussi bien.