web-dev-qa-db-ja.com

別のディレクトリでpythonスクリプトを実行するには?

解決済みこれが役立つと思う人は誰でも以下の私の答えを見てください。

2つのスクリプトa.pyとb.pyがあります。現在のディレクトリ「C:\ Users\MyName\Desktop\MAIN」で、> python a.py.

最初のスクリプトa.pyは現在のディレクトリで実行され、多数のファイルに対して何かを実行し、それらのファイルの編集バージョンで新しいディレクトリ(testA)を作成します。次に、testAのファイルに対してb.pyを実行する必要があります。

初心者の場合、b.pyスクリプトをコピーしてtestAに貼り付け、コマンド「> python b.py」を再度実行します。これにより、これらの新しいファイルに対していくつかのコマンドが実行され、これらの編集済みファイルを含むフォルダー(testB)。

私はa.pyが終了するのを待つ面倒を取り除き、その新しいディレクトリに移動し、b.pyを貼り付けてからb.pyを実行しようとしています。ディレクトリの階層を維持しながらこれらのスクリプトを実行するbashスクリプトを作成しようとしています。

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

スクリプトa.pyはスムーズに実行されますが、b.pyはまったく実行されません。 b.pyの失敗に関するエラーメッセージは表示されません。a.pyが完了すると、b.pyはその新しいディレクトリに存在しないため、実行できません。新しいディレクトリに移動するb.py内に追加できる小さなスクリプトはありますか?実際にb.pyディレクトリパスも変更しようとしましたが、うまくいきませんでした。

たとえば、b.pyの場合:

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

私はb.py内のすべてのインスタンスでmydirsをmydir_newに変更しましたが、それも違いはありませんでした... bash内の新しいディレクトリにスクリプトを移動する方法も知りません。

フォルダの小さなフローチャートとして:

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:b.pyがtestAで作成および保存されたファイルに依存している場合、メインテストフォルダー(bashスクリプトスタイル)からa.pyとb.pyを実行するにはどうすればよいですか。通常、b.pyをコピーしてtestAに貼り付けてからb.pyを実行しますが、現在は200以上のファイルがあるため、コピーと貼り付けは時間の無駄です。

7
CuriousDude

最も簡単な答えは、おそらく作業ディレクトリを変更してから、2番目の.pyファイルをそこから呼び出すことです。

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

もちろん、次のようにすべてを実行するスクリプトを作成する方が簡単かもしれません。

これをrunTests.shと同じディレクトリにa.pyとして保存します:

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

実行可能にする:

chmod +x ./runTests.sh

次に、ディレクトリを入力して実行します。

./runTests.sh
5
3D1T0R

私はb.pyを実行し、必要な場所でtestBフォルダーを作成しましたが、MAINフォルダーのままでした。疑問に思うかもしれませんが、私のb.pyスクリプトの冒頭で、通常はb.pyがどこにあってもmydir = os.getcwd()を使用します。

B.pyをMAINに保持しながら、他のディレクトリのファイルで動作させるために、私はこれを書きました:

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

Bashスクリプトの実行が機能するようになりました!

4
CuriousDude

b.pyスクリプトは、ディレクトリ名をパラメーターとして使用できます。 b.pyに渡される最初のパラメーターにアクセスするには:

import sys
dirname = sys.argv[1]

次に、指定されたディレクトリ内のファイルを次のように繰り返します。

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

ファイルを処理するその他のオプションについては、glob.globおよびos.walkも参照してください。

1
Mark Tolonen

すでに答えがありますが、私はまだ楽しさのないスクリプトを作成しました。私はpython3のためにそれを書いたので、v2.xでそれを実行するためにいくつかの小さなことを微調整する必要があります(例:プリント)。

とにかく...コードはa.pyの場所に関連する新しいフォルダーを作成し、スクリプトb.pyを作成してコードを入力し、bを実行してbの結果とエラーを表示します。

結果のパス構造は次のとおりです。testFolder | -testA | | -a.py | -testB | | -b.py

コードは次のとおりです。

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 __name__ == "__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 __name__ == '__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

新しいコードファイルを作成してコードを入力する代わりに、もちろん次のように既存のコードファイルをコピーするだけです。 pythonでファイルをコピーするにはどうすればよいですか

1
Philipp Lange