简体   繁体   English

Bash执行时异步Python函数调用(通过Python Popen)

[英]Async Python function call upon a Bash execution (through Python Popen)

I am executing a bash command (that downloads a file) inside a Python script. 我正在Python脚本内执行bash命令(下载文件)。

def execBashCmd(bash_cmd):
     process = Popen([bash_cmd], stdout=PIPE, stderr=PIPE, shell=True)

The bash command outputs a progression (refreshed) in stdout as follow: bash命令在stdout中输出进度(刷新),如下所示:

Downloading File - 20.66 MiB/165.31 MiB

I would like to be able to call a python function at a regular interval to update the progression (that I would catch with a regex or something like this) somewhere in my python code. 我希望能够以固定的间隔调用python函数以在我的python代码中的某处更新进度(我会用正则表达式或类似的东西捕获)。

cmd = "gsutil cp -n ...."     # A Bash command downloading a file and displaying a status in stdout while busy.
code = utils.execBashCmd(cmd)
self.setProgress(BASH_CURRENT_PROGRESS)  # This line should be asynchrone and called upon the bash command lifetime

Is there a way to achieve this? 有没有办法做到这一点?

I would like to be able to call a python function at a regular interval to update the progression (that I would catch with a regex or something like this) somewhere in my python code. 我希望能够以固定的间隔调用python函数以在我的python代码中的某处更新进度(我会用正则表达式或类似的东西捕获)。

At any time you can call eg os.read(process.stdout.fileno(), 4096) and get the bash command's output progression (possibly multiple updates) at that time, provided the number of bytes is big enough. 只要字节数足够大,您就可以随时调用os.read(process.stdout.fileno(), 4096)并获取bash命令的输出进度(可能是多次更新)。 If you don't want this call to block until the next progress output if there isn't yet, you can make the pipe non-blocking with 如果您不希望此调用在下一个进度输出之前一直阻塞,则可以使管道变为非阻塞状态

fcntl.fcntl(process.stdout, fcntl.F_SETFL, os.O_NONBLOCK)

and do eg 并做例如

try:
    progress = os.read(process.stdout.fileno(), 4096)
except OSError:
    # no progress data
    pass

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM