web-dev-qa-db-ja.com

Pythonからプログラムを実行する方法パスのスペースが原因でos.systemが失敗する

外部プログラムを実行する必要があるPythonスクリプトがありますが、何らかの理由で失敗します。

次のようなスクリプトがあるとします。

import os;
os.system("C:\\Temp\\a b c\\Notepad.exe");
raw_input();

その後、次のエラーで失敗します。

'C:\ Temp\a'は、内部コマンドまたは外部コマンド、操作可能プログラム、またはバッチファイルとして認識されません。

引用符でプログラムをエスケープすると、

import os;
os.system('"C:\\Temp\\a b c\\Notepad.exe"');
raw_input();

それでうまくいきます。しかし、パラメータを追加すると、再び機能しなくなります。

import os;
os.system('"C:\\Temp\\a b c\\Notepad.exe" "C:\\test.txt"');
raw_input();

プログラムを実行してそれが完了するのを待つ正しい方法は何ですか?ジョブを実行して終了するだけのビジュアルプログラムなので、そこから出力を読み取る必要はありませんが、完了するまで待つ必要があります。

また、プログラムをスペースのないパスに移動することもできません。


これもうまくいきません。

import os;
os.system("'C:\\Temp\\a b c\\Notepad.exe'");
raw_input();

一重引用符と二重引用符が入れ替わっていることに注意してください。

ここでメモ帳へのパラメータの有無にかかわらず、それはエラーメッセージで失敗します

ファイル名、ディレクトリ名、またはボリュームラベルの構文が正しくありません。

subprocess.call は、さまざまなシェルの引用規約に対処しなければならないという問題を回避します。文字列ではなくリストを受け入れるので、引数はより簡単に区切られます。すなわち.

import subprocess
subprocess.call(['C:\\Temp\\a b c\\Notepad.exe', 'C:\\test.txt'])
275
Brian

これは別のやり方です。

Windowsを使用している場合は、エクスプローラでファイルをダブルクリックしたり、DOSの "start"コマンドの引数としてファイル名を指定したりします。 。

filepath = 'textfile.txt'
import os
os.startfile(filepath)

例:

import os
os.startfile('textfile.txt')

メモ帳が.txtファイルに関連付けられている場合、これはメモ帳でtextfile.txtを開きます。

62
user16738

最も外側の引用符はPython自身によって消費され、Windowsシェルはそれを見ません。上記のように、Windowsは二重引用符だけを理解します。 PythonはWindows上でスラッシュをバックスラッシュに変換するので、

os.system('"C://Temp/a b c/Notepad.exe"')

Pythonによって消費され、CMD.EXEに "C:// Temp/a b c/Notepad.exe"(Windowsパスとして、二重の円記号は不要)が渡されます。

34
Daniel Serodio

少なくともWindows 7およびPython 3.1では、Windowsのos.systemは、コマンドへのパスにスペースがある場合、コマンドラインを二重引用符で囲む必要があります。例えば:

  TheCommand = '\"\"C:\\Temp\\a b c\\Notepad.exe\"\"'
  os.system(TheCommand)

私を困惑させていた現実的な例は、VirtualBoxでドライブを複製することでした。上記のsubprocess.callソリューションは、アクセス権の問題のためにうまくいきませんでしたが、コマンドを二重引用符で囲むと、os.systemは幸せになりました。

  TheCommand = '\"\"C:\\Program Files\\Sun\\VirtualBox\\VBoxManage.exe\" ' \
                 + ' clonehd \"' + OrigFile + '\" \"' + NewFile + '\"\"'
  os.system(TheCommand)
18
Paul Hoffman
import win32api # if active state python is installed or install pywin32 package seperately

try: win32api.WinExec('NOTEPAD.exe') # Works seamlessly
except: pass
7
rahul

Windowsでショートカットを使用したときと同じ問題があるのではないかと思います。

import os;
os.system("\"C:\\Temp\\a b c\\Notepad.exe\" C:\\test.txt");
4

Python> = 3.5の場合、subprocess.runの代わりにsubprocess.callを使用する必要があります。

https://docs.python.org/3/library/subprocess.html#older-high-level-api

import subprocess
subprocess.run(['notepad.exe', 'test.txt'])
3
gbonetti

あなたのパスの間にスペースがある(path = '/home/<you>/<first-path-section> <second-path-section>')ようにあなたのDjangoウェブサーバー(Linuxで)を動かしたいとしましょう。

import subprocess

args = ['{}/manage.py'.format('/home/<you>/<first-path-section> <second-path-section>'), 'runserver']
res = subprocess.Popen(args, stdout=subprocess.PIPE)
output, error_ = res.communicate()

if not error_:
    print(output)
else:
    print(error_)

[]:

  • アクセス許可を忘れないでください。chmod 755 -R <'yor path'>
  • manage.pyは栄養補給可能です:chmod +x manage.py
0
Benyamin Jafari

Python 3.7では、 subprocess.call を使用します。生の文字列を使用して、Windowsパスを簡素化します。

import subprocess
subprocess.call([r'C:\Temp\Example\Notepad.exe', 'C:\test.txt'])
0
WestAce