Comment puis-je obtenir des commandes sudo pour utiliser les paramètres dans /root/.bashrc


9

J'ai personnalisé .bashrcavec un certain nombre d'alias, spécifiquement lletexport LS_OPTIONS='--color=auto'

Malheureusement, cela ne fonctionne pas lorsqu'il est utilisé avec sudo, j'ai donc également modifié /root/.bashrc, mais cela ne semble avoir fait aucune différence.

sudo envspectacles HOME=/rootetSHELL=/bin/bash

Comment puis-je obtenir des sudocommandes pour utiliser les paramètres dans /root/.bashrc?

Je comprends que cela ne se produit que lorsqu'il bashest exécuté de manière interactive, je suis donc ouvert à toute autre suggestion sur la façon de personnaliser.


@ daniel-gelling - J'ai toujours senti que Q était un problème XY - meta.stackexchange.com/questions/66377/what-is-the-xy-problem . Le titre implique qu'ils veulent quelque chose /root/.bashrcmais vraiment ce que le Q est après, ce sont les alias de ce fichier - ce n'est pas possible par cela - unix.stackexchange.com/questions/1496/… .
slm

@slm Ce que je suis après est l' ajout d' une méthode pour bashrc - comme je l' ai fait dans mon dossier .bashrc personnel ainsi que le fichier .bashrc pour racine à la « désactiver » l' -roption pour crontab: crontab () { [[ $@ =~ -[iel]*r ]] && echo '"r" not allowed' || command crontab "$@" ;}. Cela fonctionne lorsque vous êtes connecté en tant qu'utilisateur, mais quand je l'exécute, sudo crontab -ril s'exécute toujours.
Daniel Gelling

@DanielGelling - voyez si ma réponse fonctionne pour votre scénario.
slm

Réponses:


6

sudoexécute un exécutable, pas une commande shell. Il ne connaît donc pas les alias. Si vous exécutez sudo ls, c'est comme sudo /bin/ls, il n'utilise aucun lsalias que vous pourriez avoir.

Vous pouvez provoquer l' sudo lsextension de l'alias en mettant les éléments suivants dans votre .bashrc:

alias sudo='sudo '

Notez l'espace de fin - qui indique au shell de continuer l'expansion d'alias avec le mot qui vient après sudo. Sachez que développer des alias après sudo n'est pas toujours une bonne idée, cela dépend du type d'alias que vous avez.

De plus, sudo supprime la plupart des variables de l'environnement. Cela n'affectera pas un alias comme alias ls='ls $LS_OPTIONS', car il s'agit d'une variable shell utilisée par le shell pendant qu'il développe la commande (et l'exporter depuis .bashrcne sert à rien). Mais cela affecterait les variables utilisées par la commande, telles que LS_COLORS. Vous pouvez configurer sudo pour conserver certaines variables d'environnement en modifiant sa configuration: exécutez visudoet ajoutez la ligne

Defaults env_keep += "LS_COLORS"

Avec ces paramètres, sudo lldonnera les couleurs auxquelles vous êtes habitué.

Vous pouvez également exécuter un shell racine avec sudo -s. Ce shell chargera son fichier de configuration ( ~/.bashrcpour bash). Selon la configuration de sudo, cela peut rester HOMEdans votre répertoire personnel ou le changer en /root. Vous pouvez forcer le répertoire personnel à être défini sur root avec sudo -Hs; à l'inverse, pour conserver le répertoire personnel d'origine, exécutez sudo env HOME="$HOME" bash.


3

Merci à ceux qui ont répondu, qui m'ont incité à lire man sudoplus attentivement.

sudo -s Si aucune commande n'est spécifiée, un shell interactif est exécuté.

Ce shell interactif utilise /root/.bashrcet inclut donc mes personnalisations.

Il faut que la commande soit entrée séparément, mais c'est OK.


2

Contexte

J'ai toujours pensé que cette question était un problème XY . Le titre implique qu'ils veulent quelque chose /root/.bashrcmais en réalité, la question est les alias de ce fichier - cela est largement considéré comme impossible - Pourquoi mon script Bash ne reconnaît-il pas les alias? .

C'est essentiellement par conception que vos alias ne seront pas récupérés dans sudoet ailleurs car ils ne sont pas portables, et c'est aussi mon avis à leur sujet.

Tout ce qui se trouve dans l'environnement de l'utilisateur ne doit pas être assumé par des scripts et tout logiciel pouvant s'exécuter sur une boîte donnée. Mais je me rends compte qu'il existe des scénarios où il pourrait y avoir des alias dans un compte d'utilisateur donné $HOME/.bashrcque d'autres pourraient vouloir utiliser dans des scénarios interactifs.

À cette fin, vous pouvez simplement dire à l'interpréteur Bash de développer tous les alias qu'il trouve lors du processus de connexion en dehors des comportements de shell normaux que vous rencontrez lors de l'utilisation sudo.

Exemple

Installer

Pour configurer les choses, j'ai ajouté les alias, variables d'environnement et fonctions suivants à mon utilisateur root /root/.bashrcet à ses /root/.bash_profilefichiers.

$ grep smurf ~/.bashrc
alias brc_smurf='echo "ran alias from /root/.bashrc"'
export brc_smurf_env='var from /root/.bashrc'
bpf_smurf_func() { echo 'ran func from /root/.bash_profile'; }

$ grep smurf ~/.bash_profile
alias bpf_smurf='echo "ran alias from /root/.bash_profile"'
export bpf_smurf_env='var from /root/.bash_profile'
brc_smurf_func() { echo 'ran func from /root/.bashrc'; }

Sans rien faire ni l'un ni l'autre de ces travaux (pas de surprise):

$ sudo brc_smurf
sudo: brc_smurf: command not found

$ sudo bpf_smurf
sudo: bpf_smurf: command not found

Nous voyons que la aliascommande n'affiche aucun alias lorsqu'elle est exécutée dans sudo:

$ sudo alias
$

Ce comportement est votre indice que vous ne devez pas vous attendre à ce que les alias soient accessibles. Mais nous continuons ...

Étape # 1 - alias visibles

Si nous courons, bash -cinous pouvons inciter Bash à lire au moins notre $HOME/.bashrc:

$ sudo bash -ci 'alias' | grep smurf
alias brc_smurf='echo "ran alias from /root/.bashrc"'

Cool, alors peut-être que nous pouvons l'exécuter?

$ sudo bash -ci 'alias; brc_smurf'
bash: alias; brc_smurf: No such file or directory

Étape 2 - shopt -s expand_aliases

Nan. Encore une fois, c'est par conception, nous faisons quelque chose que nous ne sommes pas censés faire, il y a donc un certain nombre de «sécurités» que nous devons désactiver. l'autre «sécurité» est Bash.

$ sudo bash -ci 'shopt -s expand_aliases; alias; brc_smurf'
alias brc_smurf='echo "ran alias from /root/.bashrc"'
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
ran alias from /root/.bashrc

Ici, nous pouvons voir notre message /root/.bashrc, nous avons réussi à exécuter l'alias de l'utilisateur root brc_smurf.

Étape # 3 - qu'en est-il des vars env?

Si vous utilisez la méthode indiquée ci-dessus, cela devrait également fonctionner.

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env'
ran alias from /root/.bashrc
var from /root/.bashrc

Étape # 4 - qu'en est-il des fonctions?

Cela fonctionne aussi comme prévu:

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env;brc_smurf_func'
ran alias from /root/.bashrc
var from /root/.bashrc
ran func from /root/.bashrc

TLDR;

Vous pouvez le faire pour accéder aux variables d'environnement + alias à partir de /root/.bashrc:

$ sudo bash -ci 'shopt -s expand_aliases; <cmds>'

À emporter

Cette méthode active le contenu de /root/.bashrc, elle ne récupère pas le contenu de /root/.bash_profile.

Références


Oui, même s'il existe quelques différences mineures entre eux, n'entrons pas dans les détails ici ;-). Quoi qu'il en soit, pourriez-vous m'aider avec la situation que j'ai décrite dans les commentaires de la question: utiliser les fonctions .bashrcavec sudo; supprimer spécifiquement l' -roption de crontab?
Daniel Gelling

D'accord, mais cela signifierait que je devrais courir: sudo bash -ci 'alias; shopt -s expand_aliases; echo $brc_smurf_env'au lieu d'un simple sudo echo $brc_smurf_env?
Daniel Gelling

Vous pouvez supprimer le alias, c'était simplement pour les montrer, vous auriez besoin de le fairesudo bash -ci 'shopt -s expand_aliases; <cmds>'
slm

Ce serait beaucoup de taper juste pour éditer mon crontab pour root. Permettez-moi de créer un alias pour cela :-P
Daniel Gelling

@DanielGelling - yup, bienvenue à tout le plaisir dans les entrailles de la coquille.
slm

0

Il y a un tas de paramètres dans le fichier / etc / sudoers spécifiquement ou la configuration d'un environnement pour quand les commandes sudo sont exécutées (par exemple. vous ne pourrez peut-être pas faire ce que vous recherchez si cela implique l'exécution de commandes réelles dans un shell pour configurer l'environnement. Sudoing en particulier ne vous donne pas de shell de connexion root, il ne configurera donc pas de profil normal pour vous.


0

Disons que nous éditons /root/.bashrc pour être:

$ sudo su -
Password: ******
# cat ~/.bashrc

echo "root bashrc file was read"
PATH=~/bin:$PATH
echo "$PATH"
export USERVAR=set
echo "$USERVAR"

umask 022
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'

Permet de se déconnecter et de se reconnecter pour que bash lise le fichier:

# exit
$ sudo su -
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@here:~# alias l
alias l='ls $LS_OPTIONS -lA'
root@here:~# 

Comme vous pouvez le voir, le fichier a été lu, le CHEMIN a été modifié et les alias ont été définis. Tout est fonctionnel comme vous le souhaitez.

Cependant, sudo ne fonctionnera toujours pas comme prévu.

root@here:~# exit
$ sudo env | grep USERVAR              # no output 
$ sudo env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PATH n'a pas changé. Il peut y avoir des moyens de changer le chemin dans sudoers, mais je vous recommande fortement d'éviter de le faire. Et, de toute façon, les alias, les fonctions et certains autres changements ne seront toujours pas appliqués en changeant uniquement le CHEMIN. Un fichier doit être d'origine. Faire cela pour chaque script ou commande demandera à l'ordinateur d'effectuer plus de travail sans aucun avantage réel. Les scripts n'utilisent pas d'alias (il n'y a aucune utilisation pratique pour eux dans les scripts).

Alors, connectez-vous, le .bashrcfichier sera automatiquement chargé et se mettra au travail.

Vous pouvez commencer bash comme ceci:

$ sudo bash
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@mail:/home/isaac/me/temp/clocks-master#

Mais comme vous le voyez ci-dessus, le pwd (le répertoire de travail) n'a pas changé et, si vous inspectez un peu plus, certains autres paramètres n'ont pas changé également. C'est pourquoi la commande correcte est d'utiliser:

$ sudo su -

Si cette commande est trop longue à taper, créez un alias ou une fonction dans l'utilisateur (pas root) où cette commande sera utilisée, quelque chose comme:

$ alias mysu='sudo su -'
$ mysu
# 

0

TL; DR: Vous pouvez utiliser sudo -ipour exécuter une fonction définie /root/.bashrc(mais pas un alias) et également avoir accès aux variables exportées à partir de ce fichier:

arguments de la commande sudo -i 

Cependant, les alias ne fonctionnent pas, mais vous pouvez facilement les convertir en fonctions si vous souhaitez les rendre disponibles sudo -i.

Lisez la suite pour une analyse complète et plus de détails.


Il y a quelques problèmes ici, certains dans le fonctionnement de sudo et d'autres dans le fonctionnement de bash lui-même ...

Par défaut, sudone recherchera que les commandes et contournera le shell, donc la simple exécution sudo llne fonctionnera que s'il y a un llexécutable dans l'un des répertoires de $PATH. Donc, pour utiliser des alias (ou des fonctions), vous devez vous assurer qu'un shell est invoqué dans le cadre du processus.

Une façon serait d'exécuter quelque chose comme sudo shou sudo bash, bien que moderne sudo(je teste ceci sur sudo 1.8.19p1) a des options -set -ià cet effet.

Donc, un essai serait quelque chose comme sudo -s ll(ce qui équivaut à sudo bash -c 'll', en supposant que votre $SHELLest Bash, ce qui semble être le cas sur la base de ce que rcfilevous avez mentionné.) Mais cela ne fonctionne pas non plus, car il démarre le shell dans un environnement non interactif, mode sans connexion, qui ne lit aucun de ses fichiers de démarrage. C'est essentiellement la même chose que si vous écrivez un script shell et l'utilisez #!/bin/bashpour l'exécuter. Les alias (et fonctions) que vous avez dans votre ~/.bashrcne seront pas accessibles à partir de ce script ...

La prochaine -ioption est donc de créer un shell de connexion. C'est plus prometteur, car il va lire vos fichiers de démarrage! Et pourtant, sudo -i ll(équivalent à sudo bash -l -c 'll') ne fonctionnera toujours pas. Alors, comment est-ce possible, étant donné qu'il a lu la définition de l' llalias?

Eh bien, l'explication suivante ici est que, par défaut, bash ne développera pas les alias, sauf lorsque le shell est interactif ... Ce shell démarré par sudo -i(ou bash -l) est un shell de connexion , mais toujours pas interactif.

La prochaine étape consiste donc à obtenir un shell interactif , qui fonctionne alors :

sudo bash -i -c 'll'

(Avoir à la fois une connexion et une interaction est également très bien, bien sûr, bash -l -i -c ...fonctionnera.)

Une autre alternative est de continuer à utiliser un shell de connexion (non interactif) mais lui demander explicitement d'étendre les alias, donc cela fonctionnera également:

sudo bash -l -O expand_aliases -c 'll'

(Le cas où bash était interactif n'avait pas besoin d'un shell de connexion , car cela suffit pour lire les fichiers d'initialisation, mais celui-ci doit -lles lire.)

Ce sont des lignes de commande assez longues ... Et elles nécessitent également que vous citiez la commande shell entière, donc si vous appelez un alias avec des arguments, vous devrez transformer tout cela en une chaîne ... Donc c'est un peu maladroit à utiliser ...

Notez que plus tôt, je parlais d'alias et de fonctions ... C'était exprès, car les fonctions sont en fait beaucoup plus pratiques ici. Vous n'avez besoin de rien de spécial (comme avoir un shell interactif ou définir une option spécifique) pour exécuter des fonctions sur un shell, tant que vous vous approvisionnez en définition.

Donc, si vous définissez llune fonction au lieu d'un alias, vous pourrez l'utiliser directement avec le -iraccourci de sudo :

sudo -i ll

Et si vous avez une ligne de commande plus longue, avec des arguments, vous pouvez également les passer directement ici:

sudo -i ll -C -R /etc

(Comparez avec sudo bash -i -c 'll -C -R /etc'.)

Les fonctions sont également beaucoup plus flexibles et généralement plus faciles à gérer ... Il est généralement facile de convertir un alias en fonction, la seule mise en garde est de toujours utiliser "$@"là où vous vous attendez à ce que des arguments supplémentaires soient pris (généralement à la fin de la alias.)

Par exemple, cet alias:

alias ll='ls $LS_OPTIONS -l'

Pourrait être transformé en cette fonction:

ll () {
    ls $LS_OPTIONS -l "$@"
}

Ils sont, dans la plupart des cas, équivalents. Et, comme mentionné précédemment, la fonction doit être accessible directement depuis sudo -i, c'est donc un bonus supplémentaire.

J'espère que cette réponse et cette explication vous seront utiles!


DV - Je ne pense pas que cela améliore la situation plus que ce qui est déjà là non plus.
slm

1
@slm Je pense que ma réponse ajoute quelque chose, car aucune réponse précédente n'a mentionné le formulaire sudo -i command argumentspour pouvoir exécuter des fonctions à partir de /root/.bashrcet avoir des variables exportées disponibles. Mais je vois comment ma réponse a peut-être été trop longue et cette information a été quelque peu enfouie là-dedans ... J'ai donc ajouté un TL; DR pour le résumer (tout en conservant les détails techniques de l'enquête.) Veuillez jeter un autre regard.
filbranden
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.