web-dev-qa-db-fra.com

Puis-je écrire un alias qui prend une dispute?

J'ai des machines distantes, où j'ai besoin de compiler du code source. Ce que je fais normalement est d'écrire un alias, qui dit quelque chose comme:

alias g++='g++ `pkg-config --cflags opencv --libs opencv`'

Ensuite, quand je vais compiler à distance, je ferais g++ -o test test.cpp.

Pour une raison quelconque, Ubuntu ne me laissera pas faire cela. Au lieu de cela, Ubuntu fonctionne, quand je le fais:

g++ file.cpp -o file `pkg-config --cflags opencv --libs opencv`

Mais cela signifie que je ne peux pas écrire d'alias pour g ++. Existe-t-il un moyen de rédiger un alias prenant un argument? que devrais-je faire?

5
j0h

TL; DR: Utilisez command g++ dans une fonction shell au lieu de g++ dans un alias.

Comme 6.6 alias dans le manuel de référence de Bash dit:

Il n'y a pas de mécanisme pour utiliser des arguments dans le texte de remplacement, comme dans csh. Si des arguments sont nécessaires, une fonction Shell doit être utilisée (voir Fonctions Shell ).

Bien qu'un alias se développe même s'il apparaît devant du texte supplémentaire, les alias ne prennent pas eux-mêmes en charge paramètres de position (c'est-à-dire, la ligne de commande arguments ), vous ne pouvez donc pas utiliser alias pour mener à bien votre tâche actuelle. Autrement dit, vous ne pouvez pas utiliser un alias pour exécuter une commande avec des arguments spécifiés par l'utilisateur suivis de arguments supplémentaires.

Comme vous l'avez trouvé, vous pouvez utiliser un alias pour que g++ file.cpp -o file soit exécuté:

g++ `pkg-config --cflags opencv --libs opencv` file.cpp -o file

Mais pas pour faire g++ file.cpp -o file exécuter cette commande:

g++ file.cpp -o file `pkg-config --cflags opencv --libs opencv`

Donc, si vous le souhaitez, vous voudrez probablement utiliser un fonction Shell :

g++ () {
    command g++ `pkg-config --cflags opencv --libs opencv` "$@"
}

Vous pouvez:

  • Exécutez-le sur la ligne de commande et il sera défini tant que le shell actuel est en cours d'exécution, uniquement dans cette instance du shell ou
  • ajoutez-le à votre fichier ~/.bashrc, et démarrez un nouveau shell ou exécutez . ~/.bashrc.

Ceci définit une fonction appelée g++. Etant donné que, contrairement aux alias, les fonctions peuvent s’appeler par elles-mêmes, j’ai utilisé le paramètre commandintégré pour empêcher les opérations non désirées récursivité . command g++ appelle la commande externe g++. "$@" se développe à tous les arguments de ligne de commande passés à la fonction.

Dans le cas très rare où g++ vraiment avait besoin pour être un alias, vous pouvez "tricher" et le définir comme un alias pour une fonction (comme vous pouvez définir un alias pour toute autre commande). Vous pouvez le faire en définissant d'abord la fonction ou en la définissant à chaque fois dans l'alias (comme George suggère ). Cependant, vous n'avez pas besoin de le faire; une fonction fonctionnera bien.

Bien sûr, vous pourriez ne pas toujours vouloir que g++ reçoive la sortie de pkg-config --cflags opencv --libs opencv. Donc, vous voudrez peut-être mettre la définition d'alias dans un fichier et le générer uniquement quand vous le souhaitez. Si votre définition se trouve dans g++-fn.sh dans votre répertoire personnel, vous devez exécuter la fonction pour activer la fonction:

. ~/g++-fn.sh

Et pour désactiver la fonction (quelle que soit sa définition), vous pouvez exécuter:

unset -f g++

Je devrais ajouter que, pour tout sauf des programmes minuscules ou autrement triviaux, vous devriez au moins envisager d'utiliser make (au lieu d'invoquer g++ vous-même avec le résultat de pkg-config à chaque fois), comme - Steeldriver a suggéré .

4
Eliah Kagan

Puis quand je vais compiler à distance

C'est ton problème principal. Les alias définis dans le fichier de configuration local ou dans le shell interactif local ne fonctionneront pas sur un système distant. Définissez l’alias dans le ~/.bashrc de votre machine distante et il fonctionnera ensuite.

Une meilleure approche serait de définir une fonction, comme suggéré par Eliah. Mais vous devrez toujours le définir sur la machine distante, comme avec un alias.

2
Sergiy Kolodyazhnyy