J'essaie d'automatiser l'ajout d'une source de référentiel dans le fichier pacman.conf de mon Arch, mais en utilisant la commande echo
dans mon script Shell. Cependant, cela échoue comme ceci: -
Sudo echo "[archlinuxfr]" >> /etc/pacman.conf
Sudo echo "Server = http://repo.archlinux.fr/\$Arch" >> /etc/pacman.conf
Sudo echo " " >> /etc/pacman.conf
-bash: /etc/pacman.conf: Permission denied
Si j'apporte des modifications à /etc/pacman.conf manuellement à l'aide de vim, en effectuant
Sudo vim /etc/pacman.conf
et quitter vim avec :wq
, tout fonctionne bien et mon fichier pacman.conf a été mis à jour manuellement sans réclamation "autorisation refusée".
Pourquoi cela est-il ainsi? Et comment puis-je obtenir Sudo echo
travailler? (d'ailleurs, j'ai essayé d'utiliser Sudo cat
aussi mais cela a échoué avec l'autorisation refusée aussi)
Le problème est que la redirection est en cours de traitement par votre shell d'origine, et non par Sudo
. Les coquilles ne sont pas capables de lire dans les pensées et ne savent pas que ce >>
est destiné au Sudo
et non à celui-ci.
Tu dois:
Sudo)
Sudo -s
(de sorte que Sudo
utilise un shell pour traiter la redirection indiquée.)Comme @geekosaur l'a expliqué, le shell effectue la redirection avant d'exécuter la commande. Quand vous tapez ceci:
Sudo foo >/some/file
Votre processus Shell actuel crée une copie de lui-même qui tente d’abord d’ouvrir /some/file
pour l'écriture, fait alors de ce descripteur de fichier sa sortie standard et n'exécute alors que Sudo
.
Si vous y êtes autorisé (les configurations sudoer empêchent souvent de lancer des shells), vous pouvez faire quelque chose comme ceci:
Sudo bash -c 'foo >/some/file'
Mais je trouve une bonne solution en général est d'utiliser | Sudo tee
au lieu de >
et | Sudo tee -a
au lieu de >>
. C'est particulièrement utile si la redirection est la seule raison pour laquelle j'ai besoin de Sudo
en premier lieu; Après tout, exécuter inutilement des processus en tant que root est précisément ce que Sudo
a été créé pour éviter. Et utiliser echo
en tant que root n’est que stupide.
echo '[archlinuxfr]' | Sudo tee -a /etc/pacman.conf >/dev/null
echo 'Server = http://repo.archlinux.fr/$Arch' | Sudo tee -a /etc/pacman.conf >/dev/null
echo ' ' | Sudo tee -a /etc/pacman.conf >/dev/null
J'ai ajouté > /dev/null
à la fin parce que tee
envoie sa sortie à les deux le fichier nommé et à sa propre sortie standard, et je n'ai pas besoin de le voir sur mon terminal. (La commande tee
agit comme un connecteur "T" dans un pipeline physique, d'où son nom.) Et je suis passé aux guillemets simples ('
...'
) au lieu de doubles ("
..."
) pour que tout soit littéral et que je n’aie pas besoin de mettre une barre oblique inverse devant le $
dans $Arch
.
Donc, cela prend soin d'écrire dans les fichiers en tant que root en utilisant Sudo
. Maintenant, passons à une longue digression sur les manières de produire du texte contenant une nouvelle ligne dans un script Shell. :)
Tout d'abord, vous pouvez simplement regrouper tous les echo
dans un sous-shell, de sorte que vous ne devez effectuer la redirection qu'une seule fois:
(echo '[archlinuxfr]
echo 'Server = http://repo.archlinux.fr/$Arch'
echo ' ') | Sudo tee -a /etc/pacman.conf >/dev/null
Ou utilisez printf
au lieu de echo
, de sorte que vous puissiez incorporer des nouvelles lignes directement dans la chaîne à l'aide de \n
:
printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$Arch\n ' |
Sudo tee -a /etc/pacman.conf >/dev/null
Dans bash
, vous pouvez obtenir le même résultat avec echo -e
:
# BASH ONLY - NOT RECOMMENDED
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$Arch\n ' |
Sudo tee -a /etc/pacman.conf >/dev/null
Mais la plupart des obus ne feront que sortir le -e
lorsque vous essayez cela, ce n’est donc pas recommandé.
Avec printf
et echo -e
, ce que la commande obtient sous la forme d’une chaîne d’argument contient une barre oblique inverse littérale suivie d’un N littéral partout où vous tapez \n
, et le programme de commande lui-même (le code à l'intérieur de printf
ou echo
) le traduit en une nouvelle ligne. Dans de nombreux environnements modernes, vous avez la possibilité d’utiliser des guillemets ANSI $'
...'
, qui traduira des séquences comme \n
into littéral newlines avant que le programme de commande ne voie la chaîne, ce qui signifie que de telles chaînes fonctionnent avec n'importe quelle commande:
echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$Arch\n ' |
Sudo tee -a /etc/pacman.conf >/dev/null
Mais, bien que plus portable que echo -e
, Les guillemets ANSI sont toujours une extension non-POSIX.
Ce que je préférerais faire, ce serait d'utiliser un document ici et d'éviter le recours à echo
ou printf
entièrement:
Sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$Arch
EOF
http://www.innovationsts.com/blog/?p=2758
Comme les instructions ne sont pas aussi claires que ci-dessus, j'utilise les instructions de cet article de blog. Avec des exemples, il est donc plus facile de voir ce que vous devez faire.
$ Sudo cat /root/example.txt | gzip> /root/example.gz
- bash: /root/example.gz: autorisation refusée
Notez que c’est la deuxième commande (la commande gzip) du pipeline qui provoque l’erreur. C’est là que notre technique consistant à utiliser bash avec l’option -c entre en jeu.
$ Sudo bash -c 'cat /root/example.txt | gzip> /root/example.gz '
$ Sudo ls /root/example.gz
/root/example.gz
La sortie de la commande ls indique que la création du fichier compressé a réussi.
La deuxième méthode est similaire à la première en ce sens que nous passons une chaîne de commande à bash, mais que nous le faisons dans un pipeline via Sudo.
$ Sudo rm /root/example.gz
$ echo "cat /root/example.txt | gzip> /root/example.gz" | Sudo bash
$ Sudo ls /root/example.gz
/root/example.gz
Sudo bash -c 'echo "[archlinuxfr]" >> /etc/pacman.conf'
STEP 1 créer une fonction dans un fichier bash (write_pacman.sh
)
#!/bin/bash
function write_pacman {
tee -a /etc/pacman.conf > /dev/null << 'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/\$Arch
EOF
}
'EOF'
ne interprétera pas $Arch
variable.
STE2 fichier source bash
$ source write_pacman.sh
STEP exécuter la fonction
$ write_pacman