【问题标题】:How to quiet Python warnings in my script?如何在我的脚本中消除 Python 警告?
【发布时间】:2012-10-02 10:52:15
【问题描述】:

我想要一个 Python 脚本 grep 用于特定进程,提取它的 PID,然后杀死它。这是我正在使用的:

def main():
    # Shutdown Tomcat
    shutdownCmd = "sh ${TOMCAT_HOME}/bin/shutdown.sh"
    subprocess.call([shutdownCmd], shell=True)

    # Check for PID
    grepCmd = "ps -aef | grep tomcat"
    grepResults = subprocess.check_output([grepCmd], shell=True)

    # Get PID(s) and kill it/them.
    for i in range(1, len(grepResults), 9):
    pid = grepResults[i]
    killPidCmd = "kill -9 " + pid
    subprocess.call([killPidCmd], shell=True)

    # Exit.
    sys.exit()

但是,尽管它确实关闭了我的进程(Apache Tomcat),但每当我运行它时,我都会在终端中收到以下“警告”:

kill -l [exitstatus]
/bin/sh: 1: kill: Operation not permitted

/bin/sh: 1: kill: Illegal number: h
/bin/sh: 1: kill: Illegal number: v
/bin/sh: 1: kill: Illegal number: l
/bin/sh: 1: kill: Operation not permitted

/bin/sh: 1: kill: Illegal number: .
/bin/sh: 1: kill: Illegal number: i
/bin/sh: 1: kill: Illegal number: D
/bin/sh: 1: kill: Illegal number: l
/bin/sh: 1: kill: Illegal number: .
/bin/sh: 1: kill: Illegal number: i
/bin/sh: 1: kill: Illegal number: /
/bin/sh: 1: kill: Illegal number: s
/bin/sh: 1: kill: Illegal number: r
/bin/sh: 1: kill: Illegal number: /
/bin/sh: 1: kill: Illegal number: .
/bin/sh: 1: kill: Illegal number: c
/bin/sh: 1: kill: Illegal number: t
/bin/sh: 1: kill: Illegal number: c
/bin/sh: 1: kill: Illegal number: i
/bin/sh: 1: kill: Illegal number: r
/bin/sh: 1: kill: Illegal number: a
/bin/sh: 1: kill: Illegal number: l
/bin/sh: 1: kill: Illegal number: a
/bin/sh: 1: kill: Illegal number: g
/bin/sh: 1: kill: Illegal number: j
/bin/sh: 1: kill: Illegal number: s
/bin/sh: 1: kill: Illegal number: g
/bin/sh: 1: kill: Illegal number: 
/bin/sh: 1: kill: Illegal number: X
/bin/sh: 1: kill: Illegal number: 
/bin/sh: 1: kill: Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or
kill -l [exitstatus]
/bin/sh: 1: kill: Illegal number: n
/bin/sh: 1: kill: Illegal number: i
/bin/sh: 1: kill: Illegal number: /
/bin/sh: 1: kill: Illegal number: s
/bin/sh: 1: kill: Illegal number: r
/bin/sh: 1: kill: Illegal number: /
/bin/sh: 1: kill: Illegal number: .
/bin/sh: 1: kill: Illegal number: c
/bin/sh: 1: kill: Illegal number: t
/bin/sh: 1: kill: Illegal number: e
/bin/sh: 1: kill: Illegal number: 
/bin/sh: 1: kill: Illegal number: h
/bin/sh: 1: kill: Illegal number: h
/bin/sh: 1: kill: Illegal number: n
/bin/sh: 1: kill: Illegal number: /
/bin/sh: 1: kill: Illegal number: o
/bin/sh: 1: kill: Illegal number: .
/bin/sh: 1: kill: Illegal number: e
/bin/sh: 1: kill: Operation not permitted

/bin/sh: 1: kill: Illegal number: n
/bin/sh: 1: kill: Illegal number: a
/bin/sh: 1: kill: Illegal number: o
/bin/sh: 1: kill: Illegal number: e
/bin/sh: 1: kill: Illegal number: x
/bin/sh: 1: kill: Illegal number: c
/bin/sh: 1: kill: Illegal number: t
/bin/sh: 1: kill: Illegal number: a
/bin/sh: 1: kill: Illegal number: m
/bin/sh: 1: kill: Operation not permitted

/bin/sh: 1: kill: Illegal number: m
/bin/sh: 1: kill: Illegal number: .
/bin/sh: 1: kill: Illegal number: t
/bin/sh: 1: kill: Illegal number: s
/bin/sh: 1: kill: Illegal number: z
/bin/sh: 1: kill: Illegal number: a
/bin/sh: 1: kill: Illegal number: v
/bin/sh: 1: kill: Illegal number: t
Killed

任何 Python meastros 都可以查看脚本并弄清楚为什么我会收到所有这些 /bin/sh: 1: kill: Illegal number: <whatever> 警告/错误/输出吗?关于如何修复它们的任何建议?提前致谢!

【问题讨论】:

  • 正如 Randall L. Schwartz 所说,“useless use of kill -9”!
  • 请仔细查看@dbr 的解决方案。他的版本是这类脚本的样子。

标签: python grep pid sigkill


【解决方案1】:
for i in range(1, len(grepResults), 9):
    pid = grepResults[i]
    killPidCmd = "kill -9 " + pid
    subprocess.call([killPidCmd], shell=True)

看起来您的 grepResults 是一些纯字符串,并且您正在从中挑选单个字符。这就是为什么kill 抱怨你给它的奇怪数字(不是数字而是字符)。检查此命令的输出,然后您应该会看到出了什么问题:

grepResults = subprocess.check_output([grepCmd], shell=True)

插入类似的内容并检查pid 是否适合您。还要确保条件 (if 'grep' in line) 适合且不匹配其他流程。也许您必须在此处添加更多 if 子句。

import subprocess
grepCmd = "ps -aef | grep tomcat"
grepResults = subprocess.check_output([grepCmd], shell=True)
for line in grepResults.strip().split('\n'):
    if 'grep' in line: 
        continue
    pid = line.split()[1]
else:
    pid = None
# print pid

如果pidNone,它应该退出并出错,因为没有找到正在运行的服务。如果你想杀死多个pid,当然你必须创建一些列表,或者直接杀死这个循环中的pid。

【讨论】:

  • 谢谢@Michael (+1) - 我想这是有道理的。有没有办法重写这个,所以我没有kill 抱怨这些“奇怪”的数字?再次感谢!
【解决方案2】:

您可以尝试使用./script.py 2>/dev/nullstderr 重定向到/dev/null 以消除这些消息。

【讨论】:

  • 谢谢@Anton Guryanov (+1) - 我应该在哪里添加这个(在脚本中,或者当我调用脚本时)?最好在 Python 中执行此操作,因此我只需要调用 python myshutdownscript.py 并且不会收到警告/错误消息。另外,您能向我解释一下这些是什么,以及为什么我会看到它们吗?再次感谢!
  • 不要这样做。您的脚本严重损坏,您最好修复它,而不是隐藏错误!
  • @Michael 是的,它已经坏了,但只要它没有造成任何伤害,你就可以抑制错误。 @pnongrata 使用python myshutdownscript.py 2>/dev/null,但一般情况下不要这样做,如上所述。您也可以考虑使用 bash 脚本,它似乎更适合您的情况。
  • 好吧,它是在盲目地试图杀死进程。如果字符串中确实有数字,它将开始杀死这些进程。事实上,在解析的字符串中有 are 个数字,因此它会定期尝试杀死进程 0-9。如果你有一个长时间运行的服务器,这些 PID 迟早会被重用,然后这个脚本会启动并使用 SIGTERM 杀死它们。这至少不是我所理解的服务器管理的良好实践......
【解决方案3】:

问题是您将 grep 输出视为一个列表,而实际上它是一个字符串.. 更改您的行:

killPidCmd = "kill -9 " + pid

收件人:

killPidCmd = "echo kill -9 " + pid

..看看输出,问题就清楚了。

脚本的略微调整版本,不使用shell=True(很少需要,并且会导致shell转义问题),相当于Python中的grep,

import os
import subprocess


def main():
    # Shutdown Tomcat
    scriptPath = "%s/bin/shutdown.sh" % (os.environ[TOMCAT_HOME])
    shutdownCmd = ["sh", scriptPath]
    subprocess.call(shutdownCmd)

    # Check for PID
    psCmd = ["ps", "-aef"]
    p = subprocess.Popen(psCmd, stdout=subprocess.PIPE)
    so, se = p.communicate()

    grep = [line for line in so.splitlines() if "python" in line]

    for line in grep:
        pid = line.split()[1] # Second column
        killPidCmd = ["kill", "-9", pid]
        subprocess.call(killPidCmd)

if __name__ == '__main__':
    main()

我再次建议您将 killPidCmd = ["kill", "-9", pid] 更改为 killPidCmd = ["echo", "kill", "-9", pid] 以验证一切正常

也就是说,这作为一个 shell 脚本会简单得多:

${TOMCAT_HOME}/bin/shutdown.sh

pids=$(ps -aef | grep tomcat | awk '{print $2}')
kill -9 ${pids}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 2018-08-03
    • 1970-01-01
    • 2021-01-12
    • 2020-10-08
    • 1970-01-01
    相关资源
    最近更新 更多