web-dev-qa-db-fra.com

Utilisez les commandes de bang (ex. '!!') de bash dans les scripts et les alias?

Est-il possible d'utiliser les soi-disant commandes bang (! + commande/symbole, comme par exemple !! ou !$:p) dans des scripts bash et des alias bash?

Je voulais ajouter la ligne

alias getit='Sudo apt-get install !!'

dans mon fichier ~/.bashrc pour pouvoir installer une commande introuvable en tapant getit après l’appel non abouti à la commande elle-même, semblable au comportement de l’outil The Fuck =, juste avec moins de jurons ...

Cependant, cette ligne ne fonctionne pas comme le montre le résultat ci-dessous:

$ cowsay
The application »cowsay« is currently not installed.
You can install it by typing:
Sudo apt-get install cowsay

$ getit
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package !!

$ 

Notez que j'ai moi-même traduit la sortie de la première commande de l'allemand, car LANG=C ne fonctionnait pas avec cela ... Pour une raison quelconque.

Quoi qu'il en soit, vous pouvez voir que la commande bang de l'alias n'est pas interprétée pour être remplacée par la dernière commande exécutée, mais reste la même chaîne. J'ai déjà découvert que les commandes éclatées ne fonctionnent généralement que dans le shell interactif et donc pas dans les scripts.

Ce paramètre peut-il être modifié pour que !! soit interprété comme la dernière chaîne de commande exécutée dans les scripts? Qu'en est-il des pseudonymes, est-ce possible là?

6
Byte Commander

Le développement de l'historique est effectué avant le développement de l'alias. Vous devrez donc utiliser la fonction intégrée history pour effectuer l'expansion vous-même:

alias getit='Sudo apt-get install $(history -p !!)'

Toutefois, l’alias ci-dessus utilise la dernière commande exécutée en tant qu’argument pour Sudo apt-get install, ce qui signifie que si nous avions fourni un argument à la commande échouée (comme cowsay "Hello"), cet argument apparaît également dans la liste des paquets à installer (Sudo apt-get install cowsay "Hello").

Comme cela n’est pas voulu, nous devrions modifier l’alias comme steeldriver suggéré et utiliser !:0 au lieu de !! pour obtenir uniquement le premier mot (le nom de la commande):

alias getit='Sudo apt-get install $(history -p !:0)'

Nous devons toujours veiller à ce que cette procédure ne fonctionne que si le nom de la commande ayant échoué et le nom de son package sont égaux. Ce serait par exemple ne fonctionne pas pour la commande lynx (un navigateur CLI), car il est inclus dans le package lynx-cur.

10
muru