如何作为create_subprocess_shell协同程序的一部分访问标准输出?

2024-05-13 18:25:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个python脚本,它为数百个子文件夹中的每一个子文件夹调用3个shell脚本。这些脚本对AWS S3进行ls调用,但从服务器接收响应的速度很慢,因此我决定异步编写此代码

我已经为这个问题建模了一个更简单的版本,我为三个参与者中的每一个调用了三个shell脚本。为了理解如何异步调用shell脚本,我下面使用的shell脚本不会ping AWS,它们只是打印随机数。我只是尝试捕获randomList.sh的输出,并将其作为列表(或其他我稍后将决定的数据类型)返回

我的问题:如何访问脚本调用的输出

#randomList.sh

x=$(( ( RANDOM % 10 )  + 1 ))
echo "sleeping for $x for $1"
sleep $x
x=$(( ( RANDOM % 10 )  + 1 ))
echo "sleeping for $x for $1"
sleep $x
x=$(( ( RANDOM % 10 )  + 1 ))
echo "sleeping for $x for $1"
sleep $x

import asyncio
import subprocess

async def callScript(script, participant):
    call = "./" + script + " " + participant
    proc = asyncio.create_subprocess_shell(call, stdout=subprocess.PIPE)
    result = await proc
    #HELP!
    #this is where i'm not sure how to access stdout..
    output = result.communicate()
    print(output)
    return output


async def callParticipant(participant):
    script1 = 'randomList.sh'
    script2 = 'randomList1.sh'
    script3 = 'randomList2.sh'
    scriptCalls = []
    scriptCalls.append(asyncio.create_task(callScript(script1, participant)))
    scriptCalls.append(asyncio.create_task(callScript(script2, participant)))
    scriptCalls.append(asyncio.create_task(callScript(script3, participant)))
    results = await asyncio.gather(*scriptCalls)
    return results

async def getRows():
    participants = ["1","2","3"]
    tasks = []
    for participant in participants:
        tasks.append(asyncio.create_task(callParticipant(participant)))
    rows = await asyncio.gather(*tasks)
    return rows

rows = asyncio.run(getRows())

编辑,自己解决 请参阅callScript函数。请注意,我还将rows = asyncio.run(getRows())放入了main()函数中,但这与解决方案无关

async def callScript(script, participant):
    call = "./" + script + " " + participant
    #I CHANGED THE FOLLOWING LINES
    proc = await asyncio.create_subprocess_shell(call, stdout=asyncio.subprocess.PIPE)
    stdout = await proc.communicate()
    output = stdout[0]
    output = output.decode('ascii')
    output = output.split()
    return output


async def callParticipant(participant):
    script1 = 'randomList.sh'
    script2 = 'randomList1.sh'
    script3 = 'randomList2.sh'
    scriptCalls = []
    scriptCalls.append(asyncio.create_task(callScript(script1, participant)))
    scriptCalls.append(asyncio.create_task(callScript(script2, participant)))
    scriptCalls.append(asyncio.create_task(callScript(script3, participant)))
    results = await asyncio.gather(*scriptCalls)
    return results

async def getRows():
    participants = ["1","2","3"]
    tasks = []
    for participant in participants:
        tasks.append(asyncio.create_task(callParticipant(participant)))
    rows = await asyncio.gather(*tasks)
    return rows

def main ():
    rows = asyncio.run(getRows())
    print(rows)

if __name__ == "__main__":
    main()

Tags: 脚本asynciofortaskoutputdefshcreate
1条回答
网友
1楼 · 发布于 2024-05-13 18:25:37

您需要使用await函数

  your code until  
rows = asyncio.run(getRows())
result = await rows

您可以在以下网站上阅读更多关于it如何工作的信息: https://www.aeracode.org/2018/02/19/python-async-simplified/#:~:text=When%20you%20have%20an%20asynchronous,result%20when%20you%20await%20me%22

此示例运行良好:

async def get_chat_id(name):
    await asyncio.sleep(3)
    return "chat-%s" % name

async def main():
    id_coroutine = get_chat_id("django")
    result = await id_coroutine

相关问题 更多 >