Comment passer des arguments de ligne de commande à un alias de shell?

288

Comment passer les arguments de ligne de commande à un alias? Voici un exemple:

alias mkcd = 'mkdir $ 1; cd $ 1; '

Mais dans ce cas, $ xx est traduit au moment de la création de l'alias et non au moment de l'exécution. J'ai cependant créé une solution de contournement en utilisant une fonction shell (après avoir googlé un peu) comme ci-dessous:

fonction mkcd () {
  mkdir 1 $
  cd $ 1
}

Je voulais juste savoir s'il existe un moyen de créer des alias qui acceptent les paramètres CL.
BTW - J'utilise 'bash' comme shell par défaut.

Vini
la source
2
Copie possible de l' alias Make a Bash qui prend un paramètre?
tripleee
2
O / T mais à peu près comme une alternative à la fonction mkcd, vous pouvez écriremkdir mydirectoryname && cd $_
moala

Réponses:

174

Vous avez trouvé le moyen: créez une fonction au lieu d'un alias. Le shell C a un mécanisme pour faire des arguments aux alias, mais bash et le shell Korn ne le font pas, car le mécanisme de la fonction est plus flexible et offre la même capacité.

Charlie Martin
la source
Cependant, vous n'avez pas besoin de fonctions lors de la création d'alias dans un .bashrcfichier. Par exemple, # créez un alias qui prend le numéro de port par l'alias utilisateur serve = "python -m SimpleHTTPServer $ 1" Après avoir apporté la modification dans le fichier .bashrc, assurez-vous que vous entrez la commande suivante. ~ $ source .bashrc Vous devriez pouvoir utiliser ceci comme ceci ~ $ serve 8998
kaizer1v
8
@ kaizer1v, Mon observation sur la version 4.2.46 de CentOS7.3 bash est que votre suggestion ne fonctionne pas comme vous le pensez. Parce que vous utilisez des guillemets doubles, le $ 1 est en fait évalué dans une chaîne vide et l'alias est en fait le même que l'alias serve = "python -m SimpleHTTPServer" et donc tout ce que vous passez après cet alias est également passé sur la ligne de commande. Si vous essayez cet ensemble -x; alias serve = "python -m SimpleHTTPServer $ 1 &" vous verrez l'erreur / le problème. Votre argument et la commande alias sont exécutés en tant que commandes distinctes.
PatS
279

Juste pour réitérer ce qui a été posté pour les autres obus, dans Bash les travaux suivants:

alias blah='function _blah(){ echo "First: $1"; echo "Second: $2"; };_blah'

Exécution de ce qui suit:

blah one two

Donne la sortie ci-dessous:

First: one
Second: two
Thomas Bratt
la source
4
Excellente solution. Quelques questions d'un novice bash: la fonction doit-elle être nommée avec un trait de soulignement (ou différemment du tout) ou est-ce juste pour la lisibilité? Quel est le but de la fin "; _blah" dans la définition de la fonction? Pourquoi cela ne fonctionne-t-il pas lorsque vous utilisez des guillemets doubles à la place des guillemets simples (le $ 1 n'est pas interprété correctement) même lorsque vous faites quelque chose qui ne nécessite pas de guillemets autour du $ 1? Merci à l'avance pour les conseils. J'ai une solution qui fonctionne, mais j'aime toujours mieux comprendre pourquoi cela fonctionne.
mynameispaulie
4
@mynameispaulie La fonction peut être nommée n'importe quoi. J'ai utilisé un préfixe de soulignement car c'est une astuce courante pour aider à prévenir les collisions de noms (c'est-à-dire une autre fonction du même nom)
Thomas Bratt
6
@mynameispaulie Les guillemets doubles permettent Bashde remplacer $1et $2avec les paramètres passés à la fonction. Les guillemets simples disent à Bash de ne pas faire cela.
Thomas Bratt
5
Je vois que ce combo alias / fonction copie / colle beaucoup, mais il ne semble pas avoir de but utile. L'approche standard serait de définir la fonction une fois, avec un nom sain, et de ne pas avoir d'alias.
tripleee
16
Je n'arrive pas à voir comment cela est préféré àfunction blah(){ echo "First: $1"; echo "Second: $2"; }
René Nyffenegger
57

Vous ne pouvez pas dans ksh, mais vous pouvez dans csh.

alias mkcd 'mkdir \!^; cd \!^1'

Dans ksh, la fonction est la voie à suivre. Mais si vous vouliez vraiment vraiment utiliser l'alias:

alias mkcd='_(){ mkdir $1; cd $1; }; _'
Sanjaya R
la source
Comme note latérale intéressante, je pense que la vulnérabilité d'exécution de code à distance dont tout le monde a parlé récemment implique de faire presque exactement la même chose, mais dans une variable d'environnement définie par une entrée utilisateur brute. openwall.com/lists/oss-security/2014/09/24/11
Floegipoky
@Floegipoky - Parce que c'est dans un alias et non dans une var env, c'est substantiellement différent. Le problème avec ShellShock est qu'il s'exécute lorsque la variable env est définie. La définition d'une variable env est censée être une opération sûre. Aucun script ne s'exécute lorsque l'alias ci-dessus est défini, uniquement lorsque l'alias est exécuté.
Sanjaya R
Il convient peut-être de souligner que ce cshn'est généralement pas ce qu'une personne moderne devrait vouloir utiliser. L'indirection alias-qui-crée-une-fonction-puis-exécute-cette-fonction est relativement populaire, mais n'offre aucun avantage sur une fonction appropriée pour autant que je sache. (La fonction doit de toute façon citer correctement son argument.) Vote en aval.
tripleee
17

Pour citer la page de manuel de bash:

Il n'y a aucun mécanisme pour utiliser des arguments dans le texte de remplacement. Si des arguments sont nécessaires, une fonction shell doit être utilisée (voir FONCTIONS ci-dessous).

Il semble donc que vous ayez répondu à votre propre question - utilisez une fonction au lieu d'un alias

Chris Dodd
la source
12

Vous pouvez également trouver cette commande utile:

mkdir dirname && cd $_

où dirname est le nom du répertoire que vous souhaitez créer

tdecs
la source
1
@StarDust $_est la sortie de la dernière commande unix.stackexchange.com/a/271693/169772
Taylor Edmiston
5

J'ai trouvé que les fonctions ne peuvent pas être écrites dans un ~/.cshrcfichier. Ici en alias qui prend des arguments

par exemple, des arguments passés à la commande 'find'

alias fl "find . -name '\!:1'"     
Ex: >fl abc

où abc est l'argument passé en tant que!: 1

kumar palaniappan
la source
4
Ce n'est pas utile pour l'OP, dont le shell par défaut est bash. Et la réponse de Sanjaya R a mentionné les alias csh il y a 4 ans.
Keith Thompson
1
La réponse de Sanjaya R n'a pas expliqué ce !:1que cela signifiait. J'ai dû faire défiler pour voir ici que c'était l'argument. Une bonne réponse ne laisse pas plus de questions, même si ce n'était pas pour le type de shell OPs.
searchengine27
4

La manière la plus simple est d'utiliser la fonction et non l'alias. vous pouvez toujours appeler une fonction à tout moment depuis le cli. En bash, vous pouvez simplement ajouter un nom de fonction () {commande} qui se charge de la même manière qu'un alias.

function mkcd() { mkdir $1; cd $1 ;}

Je ne suis pas sûr des autres obus

Luke Attard
la source
1

Cela fonctionne dans ksh:

$ alias -x mkcd="mkdir \$dirname; cd \$dirname;"
$ alias mkcd
mkcd='mkdir $dirname; cd $dirname;'
$ dirname=aaa 
$ pwd
/tmp   
$ mkcd
$ pwd
/tmp/aaa

L'option "-x" rend l'alias "exporté" - l'alias est visible dans les sous-coquilles.

Et sachez que les alias définis dans un script ne sont pas visibles dans ce script (car les alias sont développés lors du chargement d'un script, pas lorsqu'une ligne est interprétée). Cela peut être résolu en exécutant un autre fichier de script dans le même shell (en utilisant un point).


la source
-2

Voici un exemple de fonction simple utilisant python. Vous pouvez coller dans ~ / .bashrc
Vous devez avoir un espace après la première accolade gauche
La commande python doit être entre guillemets pour obtenir la substitution de variable
N'oubliez pas que le point-virgule à la fin

fonction count () {python -c "pour num dans xrange ($ 1): print num";}

$ count 6
0
1
2
3
4
5
$
AAAfarmclub
la source
-5

Un alias vide exécutera ses arguments:

alias DEBUG=
Peter Sharp
la source
12
Je vois par votre représentant que vous êtes nouveau sur SO (Stack Overflow). Veuillez ne pas être consterné par le vote négatif de votre réponse. Il a été rejeté parce qu'il ne répond vraiment pas à la question à laquelle l'OP (affiche originale) a demandé d'avoir répondu. Accrochez-vous et continuez d'essayer. Aussi, lorsque vous répondez, essayez d'inclure un exemple simple du fonctionnement de votre réponse et d'afficher le résultat. Cela aidera les autres à voir comment fonctionne votre réponse.
PatS