1821 votes

Créer un alias Bash qui prend un paramètre ?

J'avais l'habitude d'utiliser CShell ( csh ), qui vous permet de créer un alias qui prend un paramètre. La notation était quelque chose comme

alias junk="mv \\!* ~/.Trash"

Dans Bash, cela ne semble pas fonctionner. Étant donné que Bash possède une multitude de fonctionnalités utiles, je suppose que celle-ci a été implémentée, mais je me demande comment.

3 votes

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 a ls -la puis en tapant ls foo bar serait vraiment exécuter ls -la foo bar sur la ligne de commande".

2898voto

arunkumar Points 5350

L'alias Bash n'accepte pas directement les paramètres. Vous devrez créer une fonction.

alias n'accepte pas de paramètres mais une fonction peut être appelée tout comme un alias. Par exemple :

myfunction() {
    #do things with parameters like $1 such as
    mv "$1" "$1.bak"
    cp "$2" "$1"
}

myfunction old.conf new.conf #calls `myfunction`

D'ailleurs, les fonctions de Bash définies dans vos .bashrc et d'autres fichiers sont disponibles sous forme de commandes dans votre shell. Ainsi, par exemple, vous pouvez appeler la fonction précédente comme ceci

$ myfunction original.conf my.conf

4 votes

Merci. Je l'adore. Cela m'a permis de créer un alias pour convertir dos2unix pour perl sur mon mac. my_d2u() { tr -d '\r' < $1 > $2 } alias dos2unix=my_d2u; alias d2u=my_d2u;

73 votes

Dois-je emballer $1 entre guillemets ?

309 votes

Vous n'avez même pas besoin de déclarer l'alias. Il suffit de définir la fonction.

311voto

Mike Gleason Points 51

En affinant la réponse ci-dessus, vous pouvez obtenir une syntaxe d'une ligne comme pour les alias, ce qui est plus pratique pour les définitions ad-hoc dans un shell ou des fichiers .bashrc :

bash$ myfunction() { mv "$1" "$1.bak" && cp -i "$2" "$1"; }

bash$ myfunction original.conf my.conf

N'oubliez pas le point-virgule avant la parenthèse de fermeture. De même, pour la question actuelle :

csh% alias junk="mv \\!* ~/.Trash"

bash$ junk() { mv "$@" ~/.Trash/; }

Ou :

bash$ junk() { for item in "$@" ; do echo "Trashing: $item" ; mv "$item" ~/.Trash/; done; }

6 votes

Je préfère cette réponse, car elle montre l'itération à travers le tableau des arguments qui pourraient arriver. $1 et $2 ne sont que des cas particuliers, ce qui est également illustré dans cette réponse.

23 votes

Changement mv "$1" "$1.bak"; cp "$2" "$1" en mv "$1" "$1.bak" && cp "$2" "$1" pour ne pas perdre vos données lorsque mv rencontre des problèmes (par exemple, un système de fichiers plein).

9 votes

"N'oubliez pas le point-virgule avant la parenthèse de fermeture." Je l'ai fait plusieurs fois ! Merci :)

212voto

Evan Langlois Points 3017

La question est simplement mal posée. Vous ne faites pas un alias qui prend des paramètres parce que alias ajoute simplement un second nom pour quelque chose qui existe déjà. La fonctionnalité que le PO veut est la function pour créer une nouvelle fonction. Il n'est pas nécessaire d'aliaser la fonction puisque celle-ci a déjà un nom.

Je pense que vous voulez quelque chose comme ça :

function trash() { mv "$@" ~/.Trash; }

C'est ça ! Vous pouvez utiliser les paramètres $1, $2, $3, etc, ou simplement les remplir tous de $@

191voto

Tom Hale Points 5950

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.

87voto

Ken Tran Points 580

Il suffit de faire une fonction à l'intérieur d'un alias :

$ alias mkcd='_mkcd(){ mkdir "$1"; cd "$1";}; _mkcd'
             ^        *      ^  ^     ^  ^         ^

Vous doit mettez des guillemets doubles autour de "$1" car les guillemets simples ne fonctionneront pas. En effet, le fait d'entrechoquer les guillemets aux endroits marqués par des flèches perturbe le système. De plus, un espace à l'endroit marqué d'une étoile est nécessaire pour la fonction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X