简体   繁体   English

在nohup中使用python脚本

[英]using python script with nohup

I am having a strange problem (this is my first exercise using python). 我遇到一个奇怪的问题(这是我第一次使用python进行练习)。

I have a python script called run_class. 我有一个名为run_class的python脚本。 I want to store the output (to stdout and stderr) in run-class.out. 我想将输出(到stdout和stderr)存储在run-class.out中。

So I do the following (after looking on the web at some examples) 因此,我进行了以下操作(在某些示例中上网查看之后)

nohup ./run_class > run-class.out &

I get: 我得到:

[1] 13553 ~$ nohup: ignoring input and redirecting stderr to stdout [1] 13553〜$ nohup:忽略输入并将stderr重定向到stdout

So, all is well for now. 因此,目前一切都很好。 Indeed the program runs fine until I log out from the remote. 实际上,该程序可以正常运行,直到我从远程注销。 Then the program comes crashing down. 然后程序崩溃了。 Logging out is exactly what is causing the program to crash. 注销正是导致程序崩溃的原因。 Not logging out takes the program to run to completion. 不注销将使程序运行完成。

The run-class.out has the following error: run-class.out出现以下错误:

Traceback (most recent call last):                                              
  File "./run_class", line 84, in <module>                                      
    wait_til_free(checkseconds)                                                 
  File "./run_class", line 53, in wait_til_free                                 
    while busy():                                                               
  File "./run_class", line 40, in busy                                          
    kmns_procs = subprocess.check_output(['ps', '-a', '-ocomm=']).splitlines()  
  File "/usr/lib64/python2.7/subprocess.py", line 573, in check_output          
    raise CalledProcessError(retcode, cmd, output=output)                       
subprocess.CalledProcessError: Command '['ps', '-a', '-ocomm=']' returned non-zero exit status 1                                                               

What is wrong with my nohup? 我的nohup怎么了?

Many thanks! 非常感谢!

Note that my command works without exiting, so I don't quite understand the problem. 请注意,我的命令在不退出的情况下仍然有效,因此我不太了解这个问题。

Btw: here is the program: 顺便说一句:这是程序:

#!/usr/bin/python

import os
import os.path
import sys

ncpus = 8
datadir = "data" # double quotes preferred to allow for apostrophe's
ndatasets = 100
checkseconds = 1
basetries = 100

gs = [0.001, 0.005, 0.01, 0.05, 0.1]
trueks = [4, 7, 10]
ps = [4, 10, 100]
ns = [10, 100]  # times k left 1000 out, would be too much
shapes = ["HomSp"]
methods = ["Ma67"]


def busy(): 
    import subprocess
    output = subprocess.check_output("uptime", shell=False)
    words = output.split()
    sys.stderr.write("%s\n"%(output)) 
    try:
        kmns_procs = subprocess.check_output(['ps', '-a', '-ocomm=']).splitlines()
    except subprocess.CalledProcessError as x:
        print('ps returned {}, time to quit'.format(x))
        return
    kmns_wrds = 0
    procs = ["run_kmeans", "AdjRand", "BHI", "Diag", "ProAgree", "VarInf", "R"]
    for i in procs:
        kmns_wrds += kmns_procs.count(i)

    wrds=words[9]
    ldavg=float(wrds.strip(','))+0.8
    sys.stderr.write("%s %s\n"%(ldavg,kmns_wrds))
    return max(ldavg, kmns_wrds) >= ncpus


def wait_til_free(myseconds):
    while busy():
        import time
        import sys
        time.sleep(myseconds)

if True:
    for method in methods:
        for shape in shapes:
            for truek in trueks:
                for p in ps:
                    for n in ns:
                        actualn = n*truek
                for g in gs:
                            fnmprfix = "%sK%sp%sn%sg%s"%(shape,truek,p,n,g)
                            fname = "%sx.dat"%(fnmprfix)
                            for k in range(2*truek+2)[2:(2*truek+2)]:
                                ofprfix = "%sk%s"%(fnmprfix,k)
                                ntries =  actualn*p*k*basetries
                                ofname = "%s/estk/class/%s.dat"%(datadir,ofprfix,)
                                if os.path.isfile(ofname):
                                    continue
                                else :
                                    wait_til_free(checkseconds)
                                    mycmd = "nice ../kmeans/run_kmeans -# %s -N %s -n %s -p %s -K %s -D %s -X %s -i estk/class/%s.dat -t estk/time/%s_time.dat -z estk/time/%s_itime.dat -w estk/wss/%s_wss.dat  -e estk/error/%s_error.dat -c estk/mu/%s_Mu.dat -m %s &"%(ndatasets,ntries,actualn,p,k,datadir,fname,ofprfix,ofprfix,ofprfix,ofprfix,ofprfix,ofprfix,method)
                                    sys.stderr.write("%s\n"%(mycmd))
                                    from subprocess import call
                                    call(mycmd, shell=True)

The ps command is returning an error (a nonzero exit status). ps命令返回错误(退出状态为非零)。 Possibly just from being interrupted by a signal by your attempt to log out. 可能只是因为您尝试注销而被信号打断。 Possibly even the very SIGHUP you didn't want. 甚至可能是您不想要的SIGHUP (Note that bash will explicitly send SIGHUP to every job in the job control table if it gets SIGHUP 'd, and if the huponexit option is set, it does so for any exit reason.) (请注意, bash将明确发送SIGHUP到每一项工作在任务控制表,如果它得到SIGHUP “d,如果huponexit选项设置,它的任何退出原因这样做。)

You're using check_output . 您正在使用check_output The check part of the name means "check the exit status, and if it's nonzero, raise an exception". 名称的check部分表示“检查退出状态,如果非零,则引发异常”。 So, of course it raises an exception. 因此,当然会引发一个例外。

If you want to handle the exception, you can use a try statement. 如果要处理异常,可以使用try语句。 For example: 例如:

try:
    kmns_procs = subprocess.check_output(['ps', '-a', '-ocomm=']).splitlines()
except subprocess.CalledProcessError as x:
    print('ps returned {}, time to quit'.format(x))
    return
do_stuff(output)

But you can also just use a Popen directly. 但是您也可以直接使用Popen The high-level wrapper functions like check_output are really simple; 诸如check_output类的高级包装器功能非常简单; basically, all they do is create a Popen , call communicate on it, and check the exit status. 基本上,他们所要做的就是创建一个Popen ,称之为communicate就可以了,并检查退出状态。 For example, here's the source to the 3.4 version of check_output . 例如,这是3.4版本的check_output的源代码 You can do the same thing manually (and without all the complexity of dealing with different edge cases that can't arise for your use, creating and raising exceptions that you don't actually want, etc.). 您可以手动执行相同的操作(无需处理因使用而导致的不同情况,创建和引发您实际上不想要的异常等所有复杂性)。 For example: 例如:

ps = subprocess.Popen(['ps', '-a', '-ocomm='], stdout=subprocess.PIPE)
output, _ = ps.communicate()
if ps.poll():
    print('ps returned {}, time to quit'.format(ps.poll()))
    return
do_stuff(output)

Meanwhile, if you just want to know how to make sure you never get SIGHUP 'd, don't just nohup the process, also disown it . 同时,如果你只是想知道如何确保你永远不会得到SIGHUP “d,不只是nohup过程中,也disown

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

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