查看linux进程超时,Linux,在子进程上超时(Linux, timing out on subprocess)

Linux,在子进程上超时(Linux, timing out on subprocess)

好吧,我需要编写一个调用脚本的代码,如果脚本中的操作挂起,则终止该过程。

首选语言是Python,但我也在查看C和bash脚本文档。

似乎是一个简单的问题,但我无法决定最佳解决方案。

从目前为止的研究:

Python:有一些奇怪的线程模型,其中虚拟机一次只使用一个线程,不起作用?

C:到目前为止,首选的解决方案似乎是使用SIGALARM + fork + execl。 但SIGALARM不是堆安全的,所以它可以废弃一切?

Bash:超时计划? 所有发行版都不标准?

由于我是Linux的新手,我可能没有意识到有这些功能的500种不同的问题,所以有谁能告诉我最安全和最干净的方法是什么?

Ok, I need to write a code that calls a script, and if the operation in script hangs, terminates the process.

The preferred language is Python, but I'm also looking through C and bash script documentation too.

Seems like an easy problem, but I can't decide on the best solution.

From research so far:

Python: Has some weird threading model where the virtual machine uses one thread at a time, won't work?

C: The preferred solution so far seems to use SIGALARM + fork + execl. But SIGALARM is not heap safe, so it can trash everything?

Bash: timeout program? Not standard on all distros?

Since I'm a newbie to Linux, I'm probably unaware of 500 different gotchas with those functions, so can anyone tell me what's the safest and cleanest way?

原文:https://stackoverflow.com/questions/7244145

更新时间:2020-02-02 22:01

最满意答案

在bash中你可以做类似的事情:

用&启动后台脚本/程序

获取后台进程的进程ID

睡了一段时间

然后杀死进程(如果它已经完成你不能杀死它)或者你可以检查进程是否仍然存在然后杀死它。

例:

sh long_time_script.sh &

pid=$!

sleep 30s

kill $pid

你甚至可以尝试使用trap 'script_stopped $pid' SIGCHLD - 请参阅bash man获取更多信息。

更新:我发现其他命令超时 。 它完全符合您的需要 - 运行带有时间限制的命令。 例:

timeout 10s sleep 15s

将在10秒后杀死sleep 。

In bash you can do something similar to this:

start the script/program in background with &

get the process id of the background process

sleep for some time

and then kill the process (if it is finished you cannot kill it) or you can check if the process is still live and then to kill it.

Example:

sh long_time_script.sh &

pid=$!

sleep 30s

kill $pid

you can even try to use trap 'script_stopped $pid' SIGCHLD - see the bash man for more info.

UPDATE: I found other command timeout. It does exactly what you need - runs a command with a time limit. Example:

timeout 10s sleep 15s

will kill the sleep after 10 seconds.

2011-08-31

相关问答

自从工作了就好久没发博客,还是出来冒个泡=。= 前段时间写的一个项目需要用python的subprocess.Popen大量调用某shell命令,运行到一定量级之后就会产生内存溢出,造成大量线程阻塞,然后就会造成([Errno 24] Too many open files)这个异常。 网上有人说是close_fds=True这个参数在python2.x默认没打开,这个参数可以关闭文件描述符,试了没有作用。 后来在国外某个人的帖子找到了和我类似的问题,解决办法就是执行后把stdin,stdout,

...

问题是export不是实际的命令或文件。 它是一个内置命令,像bash和sh这样的shell,所以当你尝试一个subprocess.Popen你会得到一个异常,因为它找不到export命令。 默认情况下, os.execvp()执行一个os.execvp()来产生一个新的进程,这将不允许你使用shell内部函数。 你可以做这样的事情,但你必须改变你的电话给Popen 。 http://docs.python.org/library/subprocess.html 您可以指定shell=True使其

...

在Python 3.3+中: from subprocess import STDOUT, check_output

output = check_output(cmd, stderr=STDOUT, timeout=seconds)

output是包含命令的合并stdout,stderr数据的字节串。 不同于proc.communicate()方法,该代码会在问题文本中指定的非零退出状态引发CalledProcessError 。 我删除了shell=True因为它经常被不必要地使用。 如果

...

所以,事实证明,我在复制之前锁定了表,并且由于副本在不同的进程中运行,所以它看到一个锁定的表可以写入并挂起。 So, it turns out that I was locking the table prior to the copy, and since the copy runs in a different process, it was seeing a locked table to write to and hanging.

commands产生一个执行glob扩展的shell。 除非你传递shell = True否则subprocess不会生成一个shell。 换一种说法: p=subprocess.Popen("ls *00080",shell=True,stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

应该做与commands相同的事情。 commands spaws a shell which does the glob expansion. subproce

...

根据你的代码,唯一“不起作用”的事实是死链接导致它抛出一个OSError 。 我已将其修改为以下内容: #!/usr/bin/env python

import os

import time

import datetime

dirpath = "./"

for p, ds, fs in os.walk(dirpath):

for fn in fs:

filepath = os.path.join(p, fn)

# This catches bad li

...

在bash中你可以做类似的事情: 用&启动后台脚本/程序 获取后台进程的进程ID 睡了一段时间 然后杀死进程(如果它已经完成你不能杀死它)或者你可以检查进程是否仍然存在然后杀死它。 例: sh long_time_script.sh &

pid=$!

sleep 30s

kill $pid

你甚至可以尝试使用trap 'script_stopped $pid' SIGCHLD - 请参阅bash man获取更多信息。 更新:我发现其他命令超时 。 它完全符合您的需要 - 运行带有时间限制的命令。

...

为什么使用grep? 为什么不用Python做所有的东西? from subprocess import Popen, PIPE

p = Popen(['ping', 'google.com'], shell=False, stdin=PIPE, stdout=PIPE)

for line in p.stdout:

if 'timeout' in line.split():

# Process the error

print("Timeout error!

...

这是挂钟时间( real ),而不是在用户空间( user )或内核( system )中花费的时间。 您可以通过运行诸如sleep 60类的过程来自行测试,该过程几乎不使用任何用户或系统时间,并观察它仍然超时。 This is wall-clock time (real), not time spent in either userland (user) or the kernel (system). You can test this yourself by running a process

...

您应该能够捕获TimeoutExpired execption并忽略它 try:

cmd = subprocess.check_output([os.path.dirname(sys.argv[0])+ SCRIPT], stdin=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=1)

except subprocess.CalledProcessError e:

print(e)

except subprocess.T

...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值