web-dev-qa-db-fra.com

Comment exécuter un script python dans un répertoire différent?

Résolu voir ma réponse ci-dessous pour ceux qui pourraient trouver cela utile.

J'ai deux scripts a.py et b.py . Dans mon répertoire actuel "C:\Utilisateurs\MonNom\Bureau\MAIN", je lance> python a.py.

Le premier script, a.py s'exécute dans mon répertoire actuel, modifie un groupe de fichiers et crée un nouveau répertoire (testA) avec les versions modifiées de ces fichiers qui sont simultanément déplacés vers ce nouveau répertoire. Ensuite, je dois exécuter b.py pour les fichiers de testA.

En tant que débutant, je voudrais simplement copier et coller mon script b.py dans testA et réexécuter la commande "> python b.py", qui exécute des commandes sur ces nouveaux fichiers et crée un autre dossier (testB) avec ces fichiers modifiés.

J'essaie d'éliminer les tracas d'attendre la fin de l'a.py, de passer dans ce nouveau répertoire, de coller b.py, puis d'exécuter b.py. J'essaie d'écrire un script bash qui exécute ces scripts tout en maintenant ma hiérarchie de répertoires.

#!/usr/bin/env bash
 python a.py && python b.py

Le script a.py fonctionne bien, mais b.py ne s'exécute pas du tout. Il n'y a pas de message d'erreur à propos de l'échec de b.py, je pense simplement qu'il ne peut pas s'exécuter car une fois que a.py est terminé, b.py n'existe plus dans ce répertoire NEW . Y a-t-il un petit script à ajouter b.py qui le déplace dans le nouveau répertoire? J'ai effectivement essayé de changer les chemins de répertoire b.py également, mais cela n'a pas fonctionné.

Par exemple dans b.py:

mydir = os.getcwd() # would be the same path as a.py
mydir_new = os.chdir(mydir+"\\testA")

J'ai remplacé mydirs par mydir_new dans toutes les instances de b.py, mais cela ne faisait également aucune différence ... Je ne sais pas non plus comment déplacer un script dans un nouveau répertoire dans bash.

Comme un petit organigramme des dossiers:

MAIN # main folder with unedited files and both a.py and b.py scripts
|
| (execute a.py)
|
--------testA # first folder created with first edits of files
         |
         | (execute b.py)
         |
         --------------testB # final folder created with final edits of files

TLDR: Comment exécuter a.py et b.py à partir du dossier de test principal (style de script bash?) Si b.py repose sur des fichiers créés et stockés dans testA. Normalement, je copie et colle b.py dans testA, puis j'exécute b.py - mais maintenant, j'ai plus de 200 fichiers, donc copier et coller est une perte de temps.

5
DNAngel

La réponse la plus simple est probablement de changer votre répertoire de travail, puis appelez le deuxième fichier .py d'où il se trouve:

python a.py && cd testA && python ../b.py

Bien sûr, vous trouverez peut-être encore plus facile d'écrire un script qui fait tout pour vous, comme ceci:

Enregistrer ceci en tant que runTests.sh dans le même répertoire que a.py est:

#!/bin/sh
python a.py
cd testA
python ../b.py

Rendez-le exécutable:

chmod +x ./runTests.sh

Ensuite, vous pouvez simplement entrer votre répertoire et l'exécuter:

./runTests.sh
5
3D1T0R

J'ai réussi à obtenir que b.py exécute et produise le dossier testB là où j'en ai besoin, tout en restant dans le dossier MAIN. Pour ceux qui se demanderaient peut-être, au début de mon script b.py, j'utiliserais simplement mydir = os.getcwd (), qui est normalement partout où b.py se trouve.

Pour garder b.py dans MAIN tout en le faisant fonctionner sur des fichiers d’autres répertoires, j’ai écrit ceci:

mydir = os.getcwd() # would be the MAIN folder
mydir_tmp = mydir + "//testA" # add the testA folder name
mydir_new = os.chdir(mydir_tmp) # change the current working directory
mydir = os.getcwd() # set the main directory again, now it calls testA

L'exécution du script bash fonctionne maintenant!

3
DNAngel

Votre script b.py peut prendre le nom du répertoire en tant que paramètre. Accédez au premier paramètre passé à b.py avec:

import sys
dirname = sys.argv[1]

Ensuite, parcourez les fichiers du répertoire nommé avec:

import os
for filename in os.listdir(dirname):
    process(filename)

Voir aussi glob.glob et os.walk pour plus d'options de traitement des fichiers.

1
Mark Tolonen

malgré qu'il y ait déjà des réponses, j'ai quand même écrit un script amusant et il pourrait toujours être utile à certains égards ... Je l'ai écrit pour python3, il est donc nécessaire d'ajuster quelques petites choses pour l'exécuter sur v2.x ( par exemple les empreintes).

Quoi qu'il en soit ... le code crée un nouveau dossier par rapport à l'emplacement de a.py, crée et remplit le script b.py avec du code, exécute b et affiche les résultats et les erreurs de b.

La structure de chemin résultante est: TestFolder | -TestA | | -a.py | -testB | | -b.py

Le code est:

import os, sys, subprocess

def getRelativePathOfNewFolder(folderName):
    return "../" + folderName + "/"

def getAbsolutePathOfNewFolder(folderName):
    # create new folder with absolute path:
    #   get path of current script:
    tmpVar = sys.argv[0]
    #   separate path from last slash and file name:
    tmpVar = tmpVar[:sys.argv[0].rfind("/")]
    #   again to go one folder up in the path, but this time let the slash be:
    tmpVar = tmpVar[:tmpVar.rfind("/")+1]
    #   append name of the folder to be created:
    tmpVar += folderName + "/"

    # for the crazy ones out there, you could also write this like this:
    # tmpVar = sys.argv[0][:sys.argv[0].rfind("/", 0, 
    sys.argv[0].rfind("/")-1)+1] + folderName + "/"
    return tmpVar

if __== "__main__":
    # do stuff here:
    # ...
    # create new folder:
    bDir = getAbsolutePathOfNewFolder("testB")
    os.makedirs(bDir, exist_ok=True) # makedirs can create new nested dirs at once. e.g: "./new1/new2/andSoOn"
    # fill new folder with stuff here:
    # ...
    # create new python file in location bDir with code in it:
    bFilePath = bDir + "b.py"
    with open(bFilePath, "a") as toFill:
        toFill.write("if __== '__main__':")
        toFill.write("\n")
        toFill.write("\tprint('b.py was executed correctly!')")
        toFill.write("\n")
        toFill.write("\t#do other stuff")

    # execute newly created python file
    args = (
        "python",
        bFilePath
    )
    popen = subprocess.Popen(args, stdout=subprocess.PIPE)
    # use next line if the a.py has to wait until the subprocess execution is finished (in this case b.py)
    popen.wait()
    # you can get b.py´s results with this:
    resultOfSubProcess, errorsOfSubProcess = popen.communicate()
    print(str(resultOfSubProcess)) # outputs: b'b.py was executed correctly!\r\n'
    print(str(errorsOfSubProcess)) # outputs: None

    # do other stuff

au lieu de créer un nouveau fichier de code et de le remplir avec du code, vous pouvez bien sûr simplement copier un fichier existant comme indiqué ici: Comment copier un fichier en python?

1
Philipp Lange