Bash est lent à démarrer à cause de cette ligne dans .bashrc. Qu'est-ce qui pourrait provoquer cela?

19

Mon .bashrcdossier contient une ligne à cet effet:

alias prog="/path/to/script.sh $(find $(pwd) -name prog)"

Lorsque je commente cette ligne, Bash démarre presque instantanément lorsque j'ouvre un nouveau terminal. Avec cette ligne, il y a un délai de 4 à 5 secondes avant que mon curseur n'apparaisse.

La suppression des commandes imbriquées $(pwd), etc. accélère à nouveau également. Pourquoi cela arrive-t-il? Puis-je quand même utiliser les commandes imbriquées?

BBales
la source
4
Le problème est la findcommande, qui est exécutée au démarrage et peut être longue à exécuter, selon la structure du répertoire. Si vous utilisez des guillemets simples au lieu de guillemets doubles, findsera exécuté au moment de l'exécution, lorsque le aliasest invoqué. Cela dépend du répertoire de travail que vous souhaitez utiliser, celui en cours au moment de la déclaration ou au moment de l'exécution. Soit dit en passant $(pwd)est une façon plutôt inefficace d'exprimer .ou $PWD.
AFH
15
Je sais que ce n'est pas ce que vous demandez, mais cela ressemble beaucoup à un problème XY . Pourquoi avez-vous besoin de localiser le script à l'aide find? Une fois que vous l'avez installé, vous savez où il se trouve. Même si vous le mettez à jour fréquemment et changez son nom, vous pouvez conserver un lien symbolique vers celui-ci afin qu'il soit toujours disponible sous un nom fixe.
sleske
5
@AFH Veuillez publier les réponses comme réponses, pas comme commentaires.
David Richerby
1
@DavidRicherby - Je voulais m'assurer que c'était bien la réponse avant de poster. J'étais perplexe que le script fonctionnerait sur des fichiers trouvés dans un répertoire arbitraire.
AFH

Réponses:

45

Étant donné que la substitution de commandes se trouve entre guillemets doubles, elle est évaluée au moment où la commande est définie. Cela permet findde parcourir le contenu de votre disque dur pendant .bashrcson exécution.

En revanche, vous semblez vouloir qu'il soit évalué au moment de l'utilisation. Dans ce cas, utilisez des guillemets simples:

alias prog='/path/to/script.sh $(find "$(pwd)" -name prog)'

Notez que cet alias échouera si l'un des fichiers trouvés contient des espaces dans leurs noms. Pour éviter cela:

alias prog='find . -name prog -exec /path/to/script.sh {} +'

Cette dernière forme fonctionnera de manière fiable pour tout type de nom de fichier.

John1024
la source
1
«temps d'utilisation». Et votre deuxième ligne évite de générer un sous-shell.
rleir
11
À la baisse, à chaque fois que vous tapez prog, findil faudrait l'exécuter, alors qu'avant, il ne serait exécuté qu'une seule fois (au démarrage du shell).
el.pescado
Là encore, en raison de la mise en cache des fichiers, la deuxième fois que vous exécutez la même chose, findc'est généralement beaucoup plus rapide.
reinierpost
21
@ el.pescado Du côté positif, il est difficile d'imaginer que le comportement souhaité consiste à exécuter la commande sur les fichiers qui existaient au moment où l'utilisateur s'est connecté, plutôt que sur les fichiers qui existaient lors de l'exécution de la commande pour les traiter.
David Richerby
2
@DavidRicherby Peut-être pouvons-nous mettre en cache le chemin d'accès proget réexécuter findsi l'ancien chemin d'accès n'existe plus?
Alex Vong