私はpythonスクリプトをブレンダーに持っています
subprocess.call(os.path.abspath('D:/Test/run-my-script.sh'),Shell=True)
このシェルスクリプトに依存する他の多くのコードが続きます。完了するのを待たないのですが、どうしてですか?以下のように、Popen
の代わりにcall
を使用してみました。
_p1 = subprocess.Popen(os.path.abspath('D:/Test/run-my-script.sh'),Shell=True)
p1.wait()
_
そして私はcommincateを使ってみましたが、それでもうまくいきませんでした:
_p1 = subprocess.Popen(os.path.abspath('D:/Test/run-my-script.sh'),Shell=True).communicate()
_
このシェルスクリプトはMacOS(パスの変更後)で適切に機能し、subprocess.call(['sh', '/userA/Test/run-my-script.sh'])
を使用するときに待機します
しかし、Windowsではこれが起こります。Blenderで以下のpythonスクリプトを実行し、サブプロセス行に到達したら_Git bash
_を開いてシェルスクリプトを実行しますが、blenderは実行しません。 Git Bashが完了するのを待たずに、コンソールでHello
を出力するだけです。
_import bpy
import subprocess
subprocess.call(os.path.abspath('D:/Test/run-my-script.sh'),Shell=True)
print('Hello')
_
subprocess.call
を使用して、まさにそれを行うことができます。
サブプロセス。call(args、*、stdin = None、stdout = None、stderr = None、Shell = False、timeout =なし)
Argsで記述されたコマンドを実行します。コマンドが完了するのを待ってから、returncode属性を返します。
編集:私は何が起こっているのかについての直感を持っていると思います。 MacはBashをそのまま使用できるので(少なくとも機能的に同等のもの)、Macではコマンドが機能しますが、Windowsでは ".sh "ファイルを作成し、代わりにGit Bashを起動します。これは、起動時にいくつかのフォークを実行すると思います。
このPythonthinkとスクリプトが実行されたため、PIDはなくなっています。
私があなただったら、こうします。
tempfile
モジュールを使用して、「起動」スクリプト内に存在しない一意の絶対パスを生成します。うまくいけば、それは理にかなっています。
Popen.communicate APIを使用できます。
p1 = subprocess.Popen(os.path.abspath('D:/Test/run-my-script.sh'),Shell=True)
sStdout, sStdErr = p1.communicate()
コマンド
Popen.communicate(input=None, timeout=None)
プロセスとの対話:stdinにデータを送信します。ファイルの終わりに達するまで、stdoutおよびstderrからデータを読み取ります。プロセスが終了するのを待ちます。
subprocess.PopenおよびPopen.wait:
process = subprocess.Popen(['D:/Test/run-my-script.sh'],Shell=True, executable="/bin/bash")
process.wait()
Popenの代わりに check_call() を使用することもできます。
subprocess.run
はデフォルトで、プロセスが完了するまで待機します。
Runコマンドが失敗する場合があります。これは私の回避策です:
def check_has_finished(pfi, interval=1, timeout=100):
if os.path.exists(pfi):
if pfi.endswith('.nii.gz'):
mustend = time.time() + timeout
while time.time() < mustend:
try:
# Command is an ad hoc one to check if the process has finished.
subprocess.check_output('command {}'.format(pfi), Shell=True)
except subprocess.CalledProcessError:
print "Caught CalledProcessError"
else:
return True
time.sleep(interval)
msg = 'command {0} not working after {1} tests. \n'.format(pfi, timeout)
raise IOError(msg)
else:
return True
else:
msg = '{} does not exist!'.format(pfi)
raise IOError(msg)
次のようにos.system
を使用できます。
import bpy
import os
os.system("sh "+os.path.abspath('D:/Test/run-my-script.sh'))
print('Hello')
ひどい試みですが、シェルを管理者として実行しながら、ブレンダーを通常のユーザーとして、またはその逆を実行していますか?
一言で言えば、Windows UACは管理者と通常のユーザーの間の一種の隔離された環境であるため、このようなランダムな癖が発生する可能性があります。残念ながら、これのソースを思い出せません。最も近いのは this です。
私の問題はあなたの問題の正反対でした、wait()
は無限ループで立ち往生しました。私のpython REPLが管理者から発行されたためです。シェルであり、通常のユーザーサブプロセスの状態を読み取ることができませんでした。通常のユーザーシェルに戻すと、修正されました。このUAC snafuを使用するのは初めてではありません。