TL;DR : Faites ceci à la place
Il est beaucoup plus facile et plus lisible d'utiliser une fonction qu'un alias pour placer des arguments au milieu d'une commande.
$ wrap_args() { echo "before $@ after"; }
$ wrap_args 1 2 3
before 1 2 3 after
Si vous poursuivez votre lecture, vous apprendrez des choses que vous n'avez pas besoin de savoir sur le traitement des arguments du shell. La connaissance est dangereuse. Obtenez juste le résultat que vous voulez, avant que le côté obscur ne contrôle à jamais votre destin.
Clarification
bash
alias faire acceptent les arguments, mais seulement à la fin :
$ alias speak=echo
$ speak hello world
hello world
L'introduction d'arguments dans le milieu de commandement via alias
est en effet possible, mais ça devient moche.
N'essayez pas ça à la maison, les enfants !
Si vous aimez contourner les limites et faire ce que les autres disent être impossible, voici la recette. Mais ne m'en voulez pas si vos cheveux s'effilochent et que votre visage se retrouve couvert de suie comme un fou de science.
La solution de contournement est de passer les arguments que alias
accepte seulement à la fin à un wrapper qui les insérera au milieu et exécutera ensuite votre commande.
Solution 1
Si vous êtes vraiment contre l'utilisation d'une fonction en soi, vous pouvez utiliser :
$ alias wrap_args='f(){ echo before "$@" after; unset -f f; }; f'
$ wrap_args x y z
before x y z after
Vous pouvez remplacer $@
con $1
si vous ne voulez que le premier argument.
Explication 1
Cela crée une fonction temporaire f
qui reçoit les arguments (notez que f
est appelé à la toute fin). Le site unset -f
supprime la définition de la fonction lorsque l'alias est exécuté afin qu'elle ne traîne pas par la suite.
Solution 2
Vous pouvez également utiliser un sous-shell :
$ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'
Explication 2
L'alias construit une commande comme :
sh -c 'echo before "$@" after' _
Commentaires :
-
L'espace réservé _
est nécessaire, mais ça peut être n'importe quoi. Il est réglé sur sh
's $0
et est nécessaire pour que le premier des arguments donnés par l'utilisateur ne soit pas consommé. Démonstration :
sh -c 'echo Consumed: "$0" Printing: "$@"' alcohol drunken babble
Consumed: alcohol Printing: drunken babble
-
Les guillemets simples à l'intérieur des guillemets simples sont nécessaires. Voici un exemple où cela ne fonctionne pas avec des guillemets doubles :
$ sh -c "echo Consumed: $0 Printing: $@" alcohol drunken babble
Consumed: -bash Printing:
Ici, les valeurs des paramètres de l'interpréteur de commandes interactif $0
y $@
sont remplacés par des guillemets avant il est transmis à sh
. En voici la preuve :
echo "Consumed: $0 Printing: $@"
Consumed: -bash Printing:
Les guillemets simples assurent que ces variables ne sont pas interprétées par le shell interactif, et sont passées littéralement à sh -c
.
Vous pourriez utiliser des guillemets et \$@
mais la meilleure pratique est de citer vos arguments (car ils peuvent contenir des espaces), et \"\$@\"
est encore plus moche, mais peut vous aider à gagner un concours d'obscurcissement où les cheveux crépus sont une condition préalable à la participation.
3 votes
Duplicata possible de Shell script : Comment passer des arguments de ligne de commande à un alias UNIX ?
3 votes
Assurez-vous que vous utilisez des guillemets autour des args
"$1"
1 votes
Cette question est hors sujet pour l'OS. Elle a été répondu sur UNIX.SE et la réponse est que vous n'avez même pas besoin de vous en soucier : "Par exemple, si vous deviez aliaser
ls
als -la
puis en tapantls foo bar
serait vraiment exécuterls -la foo bar
sur la ligne de commande".11 votes
Cela n'aiderait pas à interpoler une variable au milieu d'une chaîne de caractères
4 votes
Voici le petit alias de test que j'ai utilisé pour découvrir cette erreur...
alias test_args="echo PREFIX --$1-- SUFFIX"
qui, lorsqu'il est appelé avectest_args ABCD
donne la sortie de console suivantePREFIX ---- SUFFIX ABCD
5 votes
Notez que depuis au moins 1996, la documentation de bash contient la ligne : " Pour presque tous les usages, les alias sont remplacés par les fonctions du shell ", et je pense que c'est un euphémisme. Il n'y a absolument aucune raison d'utiliser un alias au lieu d'une fonction.
2 votes
@WilliamPursell : "Absolument aucune raison" ? Tout d'abord, il y a certains cas où une fonction ne peut pas remplir le rôle d'un alias, par exemple un alias se terminant par une citation ouverte ne pourrait pas être fait comme une fonction (bien que vous ne voudriez probablement pas le faire de toute façon). De manière plus réaliste, un alias se terminant par
do
serait impossible ou peu pratique à écrire comme une fonction. Deuxièmement, pour tous vous pouvez facilement développer l'alias à l'aide de la commandeA-a
dans ZSH ouC-A-e
dans Bash (ou ce que vous configurez), alors que cette fonctionnalité n'est pas disponible pour les fonctions.0 votes
@pyrocrasty En bash, vous pouvez utiliser l'expansion de tabulation pour développer les noms de fonctions. (Je ne suis pas sûr pour zsh).
0 votes
@WilliamPursell : Je ne parle pas de la complétion de nom, je veux dire que vous pouvez développer le nom de l'alias dans sa définition en ligne. (Essayez de taper un alias et ensuite
C-A-e
avec le curseur juste après) C'est particulièrement pratique lorsque vous ne vous souvenez pas des options d'une commande mais que vous avez un alias proche de ce dont vous avez besoin.0 votes
@pyrocrasty C'est une fonctionnalité très pratique (si j'utilisais des alias !). Pour les futurs lecteurs, C-A-e est la liaison de lecture par défaut pour la fonction alias-expand-line, qui n'est pas liée par défaut en mode vi.