web-dev-qa-db-fra.com

Puis-je passer des arguments à une commande d'alias?

Je veux savoir si je peux passer un argument avec une commande d'alias.

par exemple:

alias d="dmesg|grep -iw usb|tail -5" 

d imprimera maintenant les 5 dernières lignes. Si je veux utiliser d pour imprimer un nombre différent de lignes, je dois effectuer à nouveau des modifications dans la déclaration de commande d'alias de d.

Est-il possible de modifier la déclaration d'un alias afin de ne pas avoir à ressaisir la déclaration pour modifier le nombre de lignes? C'est comme incorporer passer le nombre de lignes en tant qu'argument tout en déclarant un alias pour d? Ou existe-t-il une autre méthode pour résoudre ce problème?

17
srk_cb

Les alias ne prennent pas d'arguments. Avec un alias tel que alias foo='bar $1', le code $1 sera étendu au premier argument du shell (ce qui n'est probablement rien) lors de l'exécution de l'alias.

Donc: tilisez les fonctions, à la place.

d () {
  num=${1:-5}
  dmesg |grep -iw usb|tail -$num
}

num=${1:-5} utilise le premier argument, avec une valeur par défaut de 5 s'il n'est pas fourni.

Ensuite, vous pouvez faire:

$ d
# prints 5 lines
$ d 10
# prints 10 lines

Ou, si vous modifiez légèrement les options que vous avez utilisées:

alias d="dmesg|grep -iw usb|tail -n 5"

Ensuite, vous pouvez passer des options -n supplémentaires:

$ d
# prints 5 lines
$ d -n 10
# prints 10 lines

Si plusieurs options -n sont spécifiées pour tail, seule la dernière est utilisée.

20
muru

Vous devez avoir une fonction pour cela, comme décrit dans les SO et ici . Essayez ce qui suit:

foo() { /path/to/command "$@" ;}

et appelez le foo avec:

foo arg1 arg2 arg3
5
Ron

Contourner les limitations d'alias avec la commande group et here-string

Les alias ne peuvent pas prendre d'arguments, mais nous pouvons "simuler" cela. Prenons par exemple ma réponse sur cette question .

alias mkcd='{ IFS= read -r d && mkdir "$d" && cd "$d"; } <<<'

Points clés qui se passent ici:

  • nous utilisons read intégré pour lire une chaîne dans une variable d. Parce que nous voulons lire une chaîne complète comprenant des caractères vides (les nouvelles lignes, les tabulations, les espaces), nous utilisons IFS= et désactivons les caractères d'échappement de la barre oblique inversée avec -r.
  • <<< qui est opérateur here-string nous permet de rediriger toute chaîne que nous fournissons en tant qu'argument à mkcd alias; l'utilisation serait comme mkcd "some directory"
  • plusieurs commandes au sein d'un alias sont combinées et exécutées dans le shell actuel à l'aide de la structure { list; } (appelée group command dans le manuel bash). Notez que les espaces précédant { et ; doivent être listés séparément.

Dans votre exemple spécifique, nous pourrions faire:

alias d='{ IFS= read -r n; dmesg | grep -iw "usb" | tail -n ${n:-5};} <<<'

Nous pourrions également utiliser le fractionnement de Word pour stocker des arguments séparés par des espaces:

bash-4.3$ { read -r a1 a2; echo "$a1"; echo "$a2";}  <<< "arg1 arg2"
arg1
arg2

Ou nous pourrions utiliser des tableaux pour fournir plusieurs arguments:

bash-4.3$ { read -a arr; echo "${arr[1]}"; echo "${arr[0]}";}  <<< "arg1 arg2"
arg2
arg1

Mais est-ce une bonne approche?

Pas nécessairement. Le problème avec une telle approche est qu’elle est très spécifique - les arguments ne peuvent pas être cités facilement, ce qui signifie que nous ne pouvons avoir que des arguments sans espaces.

bash-4.3$ { read -r a1 a2; echo "$a1"; echo "$a2";}  <<< "'arg1 with space' arg2"
'arg1
with space' arg2

Ce n’est bien sûr pas quelque chose qui serait largement utilisé, simplement parce que dans le monde réel, nous devons traiter des arguments complexes, cette approche n’est donc pas très pratique. Les fonctions sont beaucoup plus flexibles. Et la nécessité de citer args string devient vite agaçante.

Malgré les limitations, cela fonctionne avec des chaînes simples comme arguments où nous pouvons nous permettre le fractionnement de Word, ce qui nous permet partiellement de donner des arguments aux alias.

3