私のコードは単純に次のとおりです。
file = 'C:\\Exe\\First Version\\filename.exe'
os.system(file)
このプログラムを実行すると、Windowsエラーが発生します:can't find the file specified.
「最初のバージョン」の途中の空白に問題があることがわかりました。問題を回避する方法をどのように見つけることができますか?
追伸:変数「ファイル」が引数として別の関数に渡されている場合はどうなりますか?
パスを引用符で囲むと機能します。
file = 'C:\\Exe\\First Version\\filename.exe'
os.system('"' + file + '"')
しかし、より良い解決策は、代わりにsubprocess
モジュールを使用することです。
import subprocess
file = 'C:\\Exe\\First Version\\filename.exe'
subprocess.call([file])
私はこれを使用しました:
import subprocess, shlex
mycmd='"C:\\Program Files\\7-Zip\\7z" x "D:\\my archive.7z" -o"D:\\extract folder" -aou'
subprocess.run(shlex.split(mycmd))
二重引用符で囲んでみてください。
file = '"C:\\Exe\\First Version\\filename.exe"'
os.system(file)
_os.system
_は、パスを引用符で囲むことにより、パスにスペースがあるバイナリを起動することは事実です。 (端末の使用に慣れている場合、これはかなり明白な解決策になるはずです。)ただし、それだけでは、この関数のより厄介な問題は解決されません...一度実行すると、コマンドに引数を追加すると問題が発生する可能性があります! (ああ!)
現在のすべての推奨事項は、この古い関数の代わりにsubprocess
モジュールを使用することです。 shlx
を使用して、フラット文字列をこれらのサブプロセス関数のリストに変換することもできます。これらのメソッドでも問題や問題が発生しましたが、これについては説明しません...また、シェルの薄いラッパーだけが必要な場合は、_os.system
_を使用する方が簡単な場合があります。コンソールでストリームを出力し、同期的に動作するなど。このような解析、ラッピング、抽象化を絶対に行わずに、シェルでコマンドを実行する組み込み関数があればいいのにと思います.。
「フィルター」のない組み込みはないので、これが_os.system
_のソリューションパッチです。これは私のオープンソースライブラリから削除されました。これは、Windows、Mac、およびUbuntuLinuxでテストされています。私はそれが100%絶対確実ではないことを知っています、そしてそれは人が望むであろうより複雑な日焼けです、しかしそれはそれほど悪くはありません。
この_system()
ラッパーを呼び出す(実行する文字列を渡す)ときは、長いパスを引用符で囲み、引用符の有無にかかわらず必要な引数も含めます。コマンドの最初の「トークン」で、MacまたはLinuxのパスにある引用符とエスケープスペースが削除されます。 Windowsでは、特定の環境にあるものを実際に解決することにより、「短い名前」を使用します。コードのその部分は少し注意が必要です。基本的に、名前解決にバッチメカニズムを使用し、stdoutのPopen()
結果に対して得られる結果を解析する目的で、結果をstderrに送り返します。ここで作業ディレクトリオプションを使用して、代替ソリューションとして最初に設定することもできます。
私はすべてのインポートを含め、あなたが必要とすることを定義していると思います。 (ソースのスピネットのコピーと貼り付け)を見逃した場合は、お知らせください。
_from os import system, getcwd, chdir
from subprocess import Popen, PIPE
import platform
__plat = platform.system()
IS_WINDOWS = __plat == "Windows"
IS_LINUX = __plat == "Linux"
IS_MACOS = __plat == "Darwin"
__SCRUB_CMD_TMPL = "{0}{1}"
__DBL_QUOTE = '"'
__SPACE = ' '
__ESC_SPACE = '\\ '
if IS_WINDOWS :
__BATCH_RUN_AND_RETURN_CMD = ["cmd","/K"] # simply assuming cmd is on the system path...
__BATCH_ONE_LINER_TMPLT = "{0} 1>&2\n" # the newline triggers execution when piped in via stdin
__BATCH_ESCAPE_PATH_TMPLT = 'for %A in ("{0}") do @echo %~sA'
from subprocess import STARTUPINFO, STARTF_USESHOWWINDOW
__BATCH_ONE_LINER_STARTUPINFO = STARTUPINFO()
__BATCH_ONE_LINER_STARTUPINFO.dwFlags |= STARTF_USESHOWWINDOW
def _system( cmd, wrkDir=None ):
if wrkDir is not None:
initWrkDir = getcwd()
print( 'cd "%s"' % (wrkDir,) )
chdir( wrkDir )
cmd = __scrubSystemCmd( cmd )
print( cmd )
system( cmd )
print('')
if wrkDir is not None: chdir( initWrkDir )
def __scrubSystemCmd( cmd ):
"""
os.system is more convenient than the newer subprocess functions
when the intention is to act as very thin wrapper over the Shell.
There is just one MAJOR problem with it:
If the first character in the command is a quote (to escape a long path
to the binary you are executing), then the limited (undesirable) parsing
built into the function can all fall apart. So, this scrub function
solves that...
"""
if not cmd.startswith( __DBL_QUOTE ): return cmd
cmdParts = cmd[1:].split( __DBL_QUOTE )
safeBinPath = _escapePath( cmdParts[0] )
args = __DBL_QUOTE.join( cmdParts[1:] ) # (the leading space will remain)
return __SCRUB_CMD_TMPL.format( safeBinPath, args )
def _escapePath( path ):
if not IS_WINDOWS: return path.replace(__SPACE, __ESC_SPACE)
return( path if __SPACE not in path else
__batchOneLinerOutput( __BATCH_ESCAPE_PATH_TMPLT.format(path) ) )
def __batchOneLinerOutput( batch ):
cmd = __BATCH_ONE_LINER_TMPLT.format( batch )
p = Popen( __BATCH_RUN_AND_RETURN_CMD, Shell=False,
startupinfo=__BATCH_ONE_LINER_STARTUPINFO,
stdin=PIPE, stdout=PIPE, stderr=PIPE )
# pipe cmd to stdin, return stderr, minus a trailing newline
return p.communicate( cmd )[1].rstrip()
_
名前にスペースが含まれているファイルの 短縮名 を使用できます。
file = 'C:\\Exe\\FirstV~1\\filename.exe'
os.system(file)