Alias ​​non disponibles lors de l'utilisation de sudo

161

Je jouais avec des alias aujourd'hui et j'ai remarqué que les alias ne semblaient pas être disponibles lorsque vous utilisiez sudo:

danny@kaon:~$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

danny@kaon:~$ ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //

danny@kaon:~$ sudo -i
root@kaon:~# ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //
root@kaon:~# exit
logout

danny@kaon:~$ sudo ll -d /
sudo: ll: command not found

Y a-t-il une raison pour laquelle vous ne pouvez pas utiliser d'alias en même temps sudo?

kemra102
la source
Avez-vous déclaré ces alias dans .bashrc sur / root /
Luciano Facchinelli
2
@ LucianoFacchinelli: /root/.bashrcne pas être lu lors de l'exécution d'une commande via sudo.
Flimm
@ Flimm: Qu'en est-il sudo -i?
Evi1M4chine

Réponses:

251

Ajoutez la ligne suivante à votre ~/.bashrc:

alias sudo='sudo '

De la bash manuel :

Les alias permettent de substituer une chaîne à un mot lorsqu'il est utilisé comme premier mot d'une commande simple. Le shell maintient une liste d’alias pouvant être définis et non définis à l’aide des commandes intégrées alias et unalias.

Le premier mot de chaque commande simple, s'il n'est pas entre guillemets, est vérifié pour voir si elle a un alias . Si c'est le cas, ce mot est remplacé par le texte de l'alias. Les caractères '/', '$', '' '', '' et tous les métacaractères du shell ou les guillemets énumérés ci-dessus peuvent ne pas apparaître sous un nom d'alias. Le texte de remplacement peut contenir toute entrée de shell valide, y compris les métacaractères de shell. Le premier mot du texte de remplacement est testé pour les alias, mais un mot identique à un alias en cours d'expansion n'est pas développé une seconde fois. Cela signifie que l'on peut alias ls à "ls -F", par exemple, et que Bash n'essaie pas de développer de manière récursive le texte de remplacement. Si le dernier caractère de la valeur de l'alias est un caractère d'espacement ou de tabulation, le mot de commande suivant après l'alias est également vérifié pour le développement de l'alias .

(Souligné par moi).
Bash ne vérifie que le premier mot d'une commande pour un alias, les mots qui suivent ne sont pas vérifiés. Cela signifie que dans une commande comme sudo ll, seul le premier mot ( sudo) est vérifié par bash pour un alias, llest ignoré. Nous pouvons dire à bash de vérifier le mot suivant après l'alias (c'est-à-dire sudo) en ajoutant un espace à la fin de la valeur d'alias.

Isaïe
la source
18
Jolie solution.
Ulidtko
Donc, fondamentalement, le problème se résume au fait que sudo est simplement programmé de manière à ne pas vérifier les alias, donc il n'est pas trouvé?
kemra102
2
La lecture de la documentation est évidemment très bénéfique :-)
biocyberman
4
Est-ce que cela va casser si j'utilise un drapeau sudo, par exemple sudo -H ll?
Mark E. Haase
1
@mehaase Oui, j'ai essayé et ça casse.
user31389
5

J'ai écrit une fonction Bash pour cela qui fait de l'ombre sudo.

Il vérifie si j'ai un alias pour la commande donnée et exécute la commande avec alias à la place du libellé avec sudodans ce cas.

Voici ma fonction en une ligne:

sudo() { if alias "$1" &> /dev/null ; then $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}" ; else command sudo $@ ; fi }

Ou bien formaté:

sudo() { 
    if alias "$1" &> /dev/null ; then 
        $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}"
    else 
        command sudo "$@"
    fi 
}

Vous pouvez l'ajouter à votre .bashrcfichier, n'oubliez pas de le rechercher ou de redémarrer votre session de terminal ultérieurement pour appliquer les modifications.

Byte Commander
la source
Ce serait merveilleux si cela fonctionnait aussi pour sudo -H ll.
Uav
3

Les alias sont spécifiques à l'utilisateur - vous devez les définir dans /root/.bashrc

Ragnar123
la source
3
Ils sont déjà sous /root/.bashrc donc ce n'est pas un problème
kemra102
1
Cette réponse ne serait correcte de la situation lorsque vous utilisez la coque elle - même en tant que root, comme sudo -sou sudo -i(et seulement si elles sont exécutées par lui - même pour obtenir un shell root, pas avec les sudo -s command...ou sudo -i command...formes) ou sudo bashou sudo suou la situation dans laquelle vous 'ont activé les connexions root et ont un shell root de cette façon. Lorsqu'un utilisateur non root s'exécute à sudo command...partir de son propre shell, le développement d'alias est effectué par son propre shell non root. sudon’élargit pas lui-même les alias. Par conséquent, telle qu’elle est appliquée à la situation décrite dans la question , cette réponse est incorrecte.
Eliah Kagan
3

La réponse de @Alvins est la plus courte. Sans aucun doute! :-)

Cependant, j'ai pensé à une solution en ligne de commande pour exécuter une commande avec alias dans sudo où il n'est pas nécessaire de redéfinir sudoavec une aliascommande.

Voici ma proposition pour ceux à qui cela pourrait intéresser:

Solution

type -a <YOUR COMMAND HERE> | grep -o -P "(?<=\`).*(?=')" | xargs sudo

Exemple

Dans le cas de la llcommande

type -a ll | grep -o -P "(?<=\`).*(?=')" | xargs sudo

Explication

lorsque vous avez un alias (tel que :), llla commande type -arenvoie l'expression avec alias:

$type -a ll
ll is aliased to `ls -l'

avec grepvous sélectionnez le texte entre l'accent `et apostrophe 'dans ce casls -l

Et xargsexécute le texte sélectionné en ls -ltant que paramètre de sudo.

Oui, un peu plus long mais complètement propre ;-) Pas besoin de redéfinir sudocomme alias.

aimé.par.Jésus
la source
3
Peut-être plus simple si vous aliasutilisiez la commande intégrée, car sa sortie est plus propre. alias llsorties alias ll='ls -ahlF'.
muru
Voici la version incorporant la suggestion de @ Muru: alias ll | sed "s/.*'\(.*\)'.*/\1/g" | xargs sudo.
ACK_stoverflow
Je pense que le but de la question initiale était de sauver du travail en évitant de sudo -icommencer par exécuter la commande avec alias, mais en le faisant tout de suite. Avoir une commande aussi complexe fait échec à cela. Vous pouvez simplement faire le premier et être beaucoup plus rapide.
Evi1M4chine
1

J'ai une autre solution intéressante qui ajoute un peu de confiance:

Utilisez la complétion bash pour remplacer automatiquement les mots sudoavec leurs alias lorsque vous appuyez sur la touche de tabulation.

Enregistrez ceci sous /etc/bash_completion.d/sudo-alias.bashcomp, et il devrait être automatiquement chargé au démarrage du shell interactif:

_comp_sudo_alias() { from="$2"; COMPREPLY=()
  if [[ $COMP_CWORD == 1 ]]; then
    COMPREPLY=( "$( alias -p | grep "^ *alias $from=" | sed -r "s/^ *alias [^=]+='(.*)'$/\1/" )" )
    return 0
  fi
  return 1
}
complete -o bashdefault -o default -F _comp_sudo_alias sudo

Ensuite, connectez-vous à un nouveau terminal, et vous devriez être prêt à partir.

Evi1M4chine
la source
Il existe un moyen d'obtenir une liste de pseudonymes, notamment destinés à être complétés:compgen -a
muru
@muru: Merci, mais dans ce cas, j'ai besoin des valeurs, pas des clés. Ainsi, le pseudonyme entré sera remplacé par. Vous tapez l'alias (comme dans sudo ll), appuyez sur [TAB], et le script trouve lldans la liste des assignations d'alias, coupe ce qui lui est attribué et l'insère. (Donc, vous auriez par exemple sudo ls -lahvF --color=auto --time-style=long-iso.)
Evi1M4chine
0

J'ai une solution différente selon laquelle vous n'avez pas besoin d'ajouter sudoun alias. Je lance Linux Mint 17.3 mais cela devrait être assez similaire à Ubuntu.

Lorsque vous êtes root, il .profileest exécuté à partir de son répertoire de base. Si vous ne savez pas quel est le répertoire personnel sous la racine, vous pouvez vérifier avec:

sudo su
echo $HOME

Comme vous pouvez le voir, la maison de rootest /root/. Vérifiez son contenu:

cd $HOME
ls -al

Il devrait y avoir un .profilefichier. Ouvrez le fichier et ajoutez les lignes suivantes:

if [ "$BASH" ]; then
    if [ -f ~/.bash_aliases];then
        . ~/.bash_aliases 
    fi
fi

Fondamentalement, ce script bash consiste à rechercher un fichier appelé .bash_aliases. Si les fichiers sont présents, il exécute le fichier.

Enregistrez le .profilefichier et créez vos alias dans .bash_aliases. Si vous avez déjà le fichier alias prêt, copiez-le à cet emplacement.

Relancez le terminal et vous êtes prêt à partir!

Karthik Ramakrishnan
la source
0

La réponse la plus votée est excellente. Cependant, si vous tapez sudo -iet passez à une invite sudo ( #), vous n'aurez pas les alias que vous souhaitez utiliser.

Pour utiliser vos alias (et tout le reste) à l' #invite, utilisez:

sudo cp "$PWD"/.bashrc /root/.bashrc

Où "$ PWD" est automatiquement développé dans "/ home / YOUR_USER_NAME"

WinEunuuchs2Unix
la source
0

@ WinEunuuchs2Unix: $PWDétend le "répertoire de travail actuel". Je pense que tu veux $HOME.

De plus, dans la plupart des cas, il est probablement préférable d’avoir un fichier racine .bashrc séparé. En fait, je voudrais en faire un fichier réel /root, un lien virtuel vers celui-ci dans le répertoire de base de l'utilisateur (par exemple, .bashrc_root) et le rechercher à partir du .bashrcfichier de l'utilisateur . Si, à un moment ultérieur, ce compte d'utilisateur privilégié n'est plus présent, le .bashrcfichier racine est toujours disponible pour les autres utilisateurs.

Shaun Griffith
la source