0

サブプロセスコマンドを非同期に実行して結果を返す関数があります。私は同期動作するように余裕があれば、私はサブプロセスモジュールには、このコールを使用する傾向があり、asyncio.create_subprocess_exec各呼び出しのコンソールウィンドウを開く

import asyncio 
async def async_subprocess_command(*args): 
    # Create subprocess 
    process = await asyncio.create_subprocess_exec(
     *args, 
     # stdout and stderr must a pipe to be accessible as process.stdout 
     stdout=asyncio.subprocess.PIPE, 
     stderr=asyncio.subprocess.PIPE) 
    # Wait for the subprocess to finish 
    stdout, stderr = await process.communicate() 

    #Remove final carriage return from string 
    stdout_formatted = stdout.decode().strip().replace('\r', '') 
    stderr_formatted = stderr.decode().strip().replace('\r', '') 
    # Return stdout and sterr 
    return stdout_formatted, stderr_formatted 

:それはこのようになります

import subprocess 
subprocess.getoutput([parameter1,parameter2,parameter3]) 

私は同期subprocess.getoutputを呼び出すと(私が呼んでいると仮定すると外部ツール)、コンソールウィンドウは開きません。私がasyncio.create_subprocess_execを非同期に呼び出すと(もう一度、私が外部ツールを呼び出していると仮定して)、コンソールウィンドウが呼び出されるたびにポップアップし、非同期呼び出しが完了するまでコンピュータを操作するのが難しくなります。

asyncio.create_subprocess_execをコンソールウィンドウがポップアップしないで非同期に呼び出すことはできますか?

+0

プロセス[作成フラグ](https://msdn.microsoft.com/en-us/library/ms684863)を使用してください。あなたは 'creationflags = DETACHED_PROCESS'を通してコンソールを全く割り当てないようにすることができます。代わりに、 'createflags = CREATE_NO_WINDOW'を介してウィンドウを作成しないコンソールを割り当てます。ウィンドウを作成しないという選択肢は無意味に見えるかもしれませんが、プロセスがまだコンソールに接続されているため、いくつかのコンソールアプリケーションとの互換性が向上し、このウィンドウレスコンソールは子プロセスによって継承されます。対照的に、デタッチされたプロセスを使用する場合、子プロセスは新しいコンソールを割り当てます。 – eryksun

+0

この情報をお寄せいただきありがとうございます。私はこれで元の機能を調整し、さらに高速化することができました。 – user3535074

答えて

1

eryksunの提案を使用して、私は追加のパラメータ(creationflags = DETACHED_PROCESS)で元の関数を使用することができました。これは、最初の答えでasyncio.create_subprocess_shell関数を使用するよりも少し速く、期待どおりに動作します。その他のメリットについては、上記のeryksunのコメントを参照してください。

async def async_subprocess_command(*args): 

    #CREATE_NO_WINDOW = 0x08000000 using detatched_process is slightly faster 
    DETACHED_PROCESS = 0x00000008 
    # Create subprocess 
    process = await asyncio.create_subprocess_exec(
     *args, 
     # stdout and stderr must a pipe to be accessible as process.stdout 
     stdout=asyncio.subprocess.PIPE, 
     stderr=asyncio.subprocess.PIPE, 
     creationflags=DETACHED_PROCESS, 
     ) 
    # Wait for the subprocess to finish 
    stdout, stderr = await process.communicate() 

    #Remove final carriage return from string 
    stdout_formatted = stdout.decode().strip().replace('\r', '') 
    stderr_formatted = stderr.decode().strip().replace('\r', '') 

    # Return stdout and sterr 
    return stdout_formatted, stderr_formatted 
0

私は別の関数に私の答えを見つけた:

async def async_subprocess_command(cmd): 
     ''' 
     cmd should be a string exactly as you 
     write into the cmd line 
     ''' 
     process = await asyncio.create_subprocess_shell(cmd, 
       stdin=None, stderr=asyncio.subprocess.PIPE, 
       stdout=asyncio.subprocess.PIPE) 

     stdout, stderr = await process.communicate() 

     stdout_formatted = stdout.decode().strip().replace('\r', '') 
     stderr_formatted = stderr.decode().strip().replace('\r', '') 

     return stdout_formatted, stderr_formatted 
+0

シェルを使うことは、特にユーザ入力からの部分文字列がある場合には、任意の 'cmd'を実行するための良い解決策ではありません。 – eryksun

+0

私の場合、ユーザー入力はありません。cmdは、どの関数が呼び出され、その関数呼び出しに適用できるパラメータに基づいてアプリケーションによって書き込まれます。 – user3535074

関連する問題