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

19

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

par exemple:

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

Imprime maintenant dles 5 dernières lignes. Si je veux utiliser d pour imprimer un nombre différent de lignes, je dois à nouveau modifier la déclaration de commande d'alias d.

Existe-t-il un moyen de modifier la déclaration d'un alias afin de ne pas avoir à retaper la déclaration pour changer le nombre de lignes. Comme incorporer le passage du nombre de lignes comme argument tout en déclarant un alias pour d? Ou existe-t-il une autre méthode pour résoudre ce problème?

srk_cb
la source
Dans (t) csh, "\! *" Référence des arguments à un alias (la barre oblique inverse est juste pour échapper au point d'exclamation qui signifie normalement "historique"), et vous pouvez même référencer des arguments individuels, bien que je ne me souvienne pas comment. Donc peut-être "tail -n \! *" Ou quelque chose (je ne pense pas que \! * Fonctionnera avec un signe moins juste avant). Cependant, je ne sais pas si cela fonctionnera en (ba) sh.
barrycarter

Réponses:

20

Les alias ne prennent pas d'arguments. Avec un alias comme alias foo='bar $1', le $1sera étendu par le shell au premier argument du shell (qui n'est probablement rien) lorsque l'alias est exécuté.

Donc: utilisez plutôt des fonctions .

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 -noptions supplémentaires :

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

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

muru
la source
Pour les personnes fonctionnellement défiées comme moi :), il pourrait être utile d'indiquer brièvement où mettre la fonction ... c'est ~/.bashrc-à- dire ou rc.localou où?
WinEunuuchs2Unix
@ WinEunuuchs2Unix partout où l'alias aurait été placé.
muru
5

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

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

et appelez le fooavec:

foo arg1 arg2 arg3
Ron
la source
4

Contournement des limitations d'alias avec la commande group et here-string

Les alias ne peuvent pas accepter d'arguments, mais nous pouvons «simuler» cela. Prenons par exemple l'exemple de ma réponse à cette question .

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

Points clés qui se produisent ici:

  • nous utilisons readinté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 (sauts de ligne, tabulations, espaces), nous utilisons IFS=et désactivons les retours arrière avec barre oblique inverse -r.
  • <<<qui est ici l'opérateur de chaîne nous permet de rediriger la chaîne que nous fournissons comme argument vers l' mkcdalias; l'utilisation serait aussimkcd "some directory"
  • plusieurs commandes au sein d'un alias sont combinées et exécutées dans le shell actuel en utilisant la { list; }structure (qui est connue comme group commanddans le bashmanuel). Notez que l'espace devant {et ;une liste individuelle de commandes sont requis.

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 la division des mots pour stocker les 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 faire face à des arguments complexes, donc cette approche n'est pas tout à fait pratique. Les fonctions sont beaucoup plus flexibles. Et la nécessité de citer la chaîne args devient rapidement agaçante.

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

Sergiy Kolodyazhnyy
la source