Pourquoi sudo ignore-t-il les alias?


22

J'utilise Ubuntu 10.04 et j'utilise upstartpour la gestion des démons. Mon application d'entreprise est exécutée en tant que démon et doit être exécutée en tant que root en raison de divers privilèges. Par exemple:

sudo start my-application-long-ID
sudo stop my-application-long-ID
etc

Je voudrais introduire un aliaspour abréger ces commandes comme quelque chose comme:

alias startapp='sudo start my-application-long-ID'

et l'exécuter comme startappet cela fonctionne, mais je préférerais ne pas avoir sudo dans l'alias.

alias startapp='start my-application-long-ID'

ne fonctionne pas en utilisant sudo startapp, en retournant sudo: startapp: command not found.

Cependant, lorsque j'ai ajouté l'alias:

alias sudo='sudo '

sudo startapp fonctionne maintenant mais je suis toujours curieux de savoir pourquoi sudo ignore les alias.


Avez-vous couru source ~/.bashrc? Cela met à jour le fichier .bashrc et rend les nouveaux alias disponibles?
manu

@manu Oui, je l'ai fait
amphibient

Réponses:


35

Je vois les informations ci-dessous d' ici .

Lorsque vous utilisez sudo, utilisez l'extension d'alias (sinon sudo ignore vos alias)

alias sudo='sudo '

La raison pour laquelle cela ne fonctionne pas est expliquée ici .

Bash vérifie uniquement le premier mot d'une commande pour un alias, tous les mots après cela 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, ll est 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.


6

Les alias et les fonctions sont définis dans un shell. Sudo est un programme externe. Donc sudo ne voit pas les alias, les fonctions ou les commandes internes du shell, seulement les commandes externes.

Les alias sont censés être des noms de commande alternatifs, donc les shells ne les développent qu'en position de commande, pas lorsqu'ils sont des arguments de commandes. Zsh prend en charge les alias globaux, qui sont développés n'importe où sur la ligne de commande, et à utiliser avec parcimonie car il existe un risque de les développer accidentellement même dans des contextes où l'alias n'a pas de sens.

Vous pouvez dire d'invoquer une sudo shell: sudo sh -c '…shell command here…'. Vos alias habituels ne seront cependant pas disponibles dans cette commande shell, car ils sont normalement stockés dans un fichier tel que ~/.bashrcou ~/.zshrcqui n'est lu que par des shells interactifs.

alias sudo='sudo ', comme proposé par Ramesh , fait que le shell développe les alias après sudo.


1
Est-ce que cela alias sudo='sudo 'fonctionne aussi pour ZSH?
CMCDragonkai


1

Une solution pour les utilisateurs de zsh

Dans bash et zsh, la fin d'un alias par un espace entraînera le shell à alias-développer le mot suivant. Cela permet à quelque chose comme ce qui suit de se développer aliasmyalias

alias 'sudo=sudo '
sudo myalias

Malheureusement, cela tombe en morceaux lorsque vous avez plus d'un mot dans votre alias (comme sudo -u someone. Cependant, vous pouvez abuser de la fonction zsh "alias globaux" pour développer manuellement les alias n'importe où dans la commande.

alias -g '$= '

Cela crée un alias global appelé $(vous pouvez utiliser n'importe quel mot de votre choix) qui se termine par un espace. Cela provoque zsh à développer le mot suivant comme un alias de commande normal. Étant donné que l'alias se développe en espaces blancs, il ne sera pas traité comme un argument. Cela permet aux éléments suivants de fonctionner.

% alias myalias=echo
% sudo -u someone myalias foo
sudo: myalias: command not found
% sudo -u someone $ myalias foo
foo

Vous pouvez même utiliser $plusieurs fois sur une même ligne de commande si vous avez une imbrication de commandes compliquée. J'ai trouvé cela suffisamment utile pour qu'il ait une place permanente dans mon zshrc, cependant l'alias est assez simple pour définir quand vous devez l'utiliser.


0

Je viens de donner une réponse alternative ici sans redéfinir sudoavec un alias.

Dans votre cas, ce serait:

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

Tout en une ligne, pas de coques supplémentaires, pas de redéfinitions d'alias. ;-)


Oh, attendez une minute - je comprends - vous utilisez xargspour supprimer les guillemets, et grep pour supprimer le début =. Un peu intelligent, mais probablement inutile. eval "sudo $(alias aliasname | cut -d= -f2-)"est probablement mieux - xargsne gérera pas toujours les guillemets correctement, et il pourrait y en avoir plus d'un =.
mikeserv

@mikeserv Je suis désolé de ne pas l'avoir compris ;-) xargsne supprime pas les guillemets. C'est grep qui prend la commande résolue entre les guillemets. Vous savez type -a alias_namerenvoie quelque chose comme alias_name is aliased to command_within_quotes. Par la façon dont je l' ai essayé votre commande et n'a pas fonctionné sur mon ubuntu :-( Est - ce le retour de. type -aDifférent entre les versions linux (je doute)?.
loved.by.Jesus

Je sais ce qui typefait - en bash. Vous comprenez cependant que les devis sont doublés non? L'avez-vous essayé avec un alias contenant des guillemets simples? Quoi qu'il en soit, vous avez raison de dire que mon truc ne fonctionne pas - vous avez besoin de l'un eval "sudo sh -c "$(...ou de l' autre eval "'sudo $(alias alias_name| cut -d\' -f2-)". Le fait est que les aliases sont essentiellement pré-arrangés eval- l' aliasutilitaire est spécifié pour sortir leur contenu afin qu'il puisse être réintroduit en toute sécurité dans le shell. Je suppose que votre xargsest alors mis en œuvre pour aplatir l'espace blanc? Soyez juste prudent avec ça, ok?
mikeserv
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.