7 votes

Différence entre deux commandes Terminal assez similaires

J'ai un script que j'exécute dans le cadre de mon développement (il s'agit du script d'activation d'un fichier Python venv environnement). La façon dont la documentation suggère de l'exécuter est d'aller dans le dossier contenant notre fichier venv et de lancer . venv/bin/activate . Cela fonctionne correctement (deuxième commande dans mon exemple).

Cependant, ce que j'aurais normalement exécuté, c'est ./venv/bin/activate c'est-à-dire en fournissant un chemin relatif vers l'activation script (première commande dans mon exemple). Cela ne fonctionne pas du tout (même si cela ne me surprend pas, car le fichier activate n'a pas les permissions d'exécution qui lui sont attachées).

My-MBP:flask-tutorial stephendewey$ ./venv/bin/activate
-bash: ./venv/bin/activate: Permission denied
My-MBP:flask-tutorial stephendewey$ . venv/bin/activate
(venv) My-MBP:flask-tutorial stephendewey$

Quelle est la commande qui fonctionne ( . venv/bin/activate ) ? Je n'ai jamais vu une telle syntaxe.

9voto

yoliho Points 340

La commande . est un alias de source, de sorte que les deux commandes sont en réalité

./venv/bin/activate

y

source venv/bin/activate

Notez également que pour que le système puisse traiter un fichier, il a besoin du chemin absolu, c'est-à-dire d'un chemin commençant par /.

Les deux noms de fichiers sont des noms relatifs, c'est-à-dire des noms qui ne peuvent être compris qu'avec la connaissance du répertoire courant, qui est la variable $(CWD).

Les deux noms de fichiers se développent en $(CWD)/./venv/bin/activate et $(CWD)/venv/bin/activate . est le répertoire courant et les deux sont donc $(CWD)/venv/bin/activate.

La différence entre l'exécution d'une commande directement ou via la source est que si elle est exécutée directement, comme dans la première commande, bash crée un nouveau sous-shell et exécute la commande dans ce sous-shell et les commandes dans le script n'affectent que ce sous-shell et lorsque le script se termine, ce sous-shell est fermé et toutes les modifications de l'environnement sont perdues. La source, en revanche, exécute la commande dans l'interpréteur de commandes actuel et toutes les modifications apportées à l'environnement demeurent après la fin du script, comme si les commandes du script avaient été saisies dans l'interpréteur de commandes actuel.

L'activation du script (je suppose qu'il s'agit de la gestion de l'environnement virtuel Python) fonctionne en modifiant le $PATH afin que l'environnement Python correct soit trouvé lorsque vous utilisez python script.py Pour ce faire, vous devez modifier votre $PATH actuel et donc l'activation du script doit être exécutée en utilisant les sources.

Voir aussi https://askubuntu.com/questions/182012/is-there-a-difference-between-and-source-in-bash-after-all y https://superuser.com/questions/176783/what-is-the-difference-between-executing-a-bash-script-vs-sourcing-it

Non pas que l'exécution d'une commande nécessite que la commande soit exécutable. La commande à exécuter est toujours un fichier et ce fichier doit être marqué comme exécutable par le système. En d'autres termes, le drapeau exécutable doit être défini dans les permissions du fichier, ce que vous pouvez voir en cliquant sur le lien suivant ls -l venv/bin/activate

source, quant à lui, se trouve dans le shell courant et se contente de lire le fichier en tant que texte, puis d'exécuter les commandes qu'il voit, de sorte que ce fichier ne doit être que lisible. Pour plus d'informations, voir https://unix.stackexchange.com/questions/291404/why-does-bashs-source-not-need-the-execution-bit J'aime cela répondre

Il s'agit plutôt d'une question de commodité : le système l'exécute directement pour moi si le bit est activé, sinon je dois le faire indirectement.

7voto

nohillside Points 82672

En man bash :

. filename [arguments]
source filename [arguments]
    Read and execute commands from filename in the current shell environment and
    return the exit status of the last command executed from filename. If filename
    does not contain a slash, filenames in PATH are used to find the directory
    containing filename. The file searched for in PATH need not be executable.

En résumé source exécute le code contenu dans le fichier script/file dans le cadre de l'environnement actuel de l'interpréteur de commandes (ce qui est différent de l'exécuter, qui l'exécute dans un shell séparé). Il est principalement utilisé pour définir les variables d'environnement, les alias, etc. à utiliser dans l'interpréteur de commandes actuel.

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X