【问题标题】:python regex doesnt match when run from cron从 cron 运行时,python 正则表达式不匹配
【发布时间】:2014-05-23 06:22:01
【问题描述】:

当作业从 cron 运行时,我很难让正则表达式匹配。当我从 cmd 行运行它时,它工作得很好。

我有一些来自 ssh 会话的输出,我需要解析一些 CPU 数据。

parts = \x1b[7mlines 24-46 \x1b[27m\x1b[K\r\x1b[KCPU 9

parts = \x1b[7mlines 25-47 \x1b[27m\x1b[K\r\x1b[K Utilization: 57%

parts = Peak Utilization Last Hour: 100% at 2014/04/09 07:07:12

parts = Avg. Utilization Last Hour: 67%

parts = 

parts = \x1b[7mlines 48-70 \x1b[27m\x1b[K\r\x1b[K

parts = \x1b[7mlines 49-71 \x1b[27m\x1b[K\r\x1b[KCPU 14

parts = Utilization: 46%

上面的示例只是有问题输出。称之为“sshoutput”我需要从包含它的行中删除\x1b[7mlines X-X \x1b[27m\x1b[K\r\x1b[K。这会为我制作的解析函数正确格式化输出。

使用的正则表达式:\\x1b\[7mlines [0-9]*-[0-9]* \\x1b\[27m\\x1b\[K\\r\\x1b\[K

删除问题字符的代码:

ansi_char = re.compile('\\x1b\[7mlines [0-9]*-[0-9]* \\x1b\[27m\\x1b\[K\\r\\x1b\[K')

def strip_ansi(with_ansi):
    return ansi_char.sub('', with_ansi)

strip_ansi(sshoutput.before)

这是一个较大脚本的一部分。当我从提示符运行它时,它运行良好并使用所有数据和正确的格式创建输出。当 cron 运行它时,所有带有 ansi crap 的行都不匹配,并且一些 CPU 数据丢失。输出格式正确,但对某些 CPU 行没有去除 ansi 字符,数据被移位并且不正确。

我一直在研究 cron 和环境变量的问题。 cron 语言环境是 POSIX,我的是 en_US.UTF-8。我想这可能与正则表达式的处理方式有关。 crontab 文件中有大量工作,我无法在全球范围内做某事。我确实尝试过:

*/1 **** export LANG=en_US.UTF-8; /pathtomyscript/myscript.py

还有什么我可以在 crontab 文件中尝试的,或者我的正则表达式可以更改吗?

感谢社区提供的任何帮助/建议。

PS,我也是一个 linux nub (RHEL 5.9) 和 python nub (Python 2.7)。我知道足够危险:)

【问题讨论】:

  • 从 cron 运行时,您在命令行上看到的颜色(例如,\x1b[7m)可能不存在。也许你可以破解一些终端的东西(TERM=xterm 等),但是如何从 cron 作业中保存你想要处理的数据并相应地调整你的正则表达式?
  • 所以添加正则表达式的原因是为了删除字符。我知道使用 cron 作业运行脚本时正在返回字符。我还应该补充一点,来自 python 脚本的 ssh 会话正在使用 pxssh。输出与我没有添加正则表达式部分相同。这(以及各种调试打印语句)使我得出这个结论。
  • 所以尝试了更多的事情,但没有运气。在运行 python 脚本之前,我创建了一个 shell 脚本来获取我的配置文件环境。那没有用。我还在 crontab 文件中尝试了“sudo -u myusername /path to script”。也没有用。
  • 这是一个删除 ansi 转义序列的正则表达式(注意字符串前面的“r”,这样我就不必转义反斜杠)r'\1b\[\d*[a-zA-Z]'。你可以从那里做第二个正则表达式。或者可能使用r'\1b\[\d*[a-zA-Z]|\r|lines \d*-\d*\s*' 删除所有垃圾。
  • 在运行作业时玩过环境变量后,有人建议从python脚本中设置TERM。这最终奏效了,我并不完全肯定为什么。 os.environ["TERM"] = "xterm-256color" 是添加到代码中的行。我猜这会将术语变量设置为某种东西,这样无论谁运行它,术语总是相同的。这个值允许正则表达式在我的配置文件和 crons 下工作。我猜测当代码中的 ssh 命令运行时,由于我的帐户和 cron 的 TERM 值不同,因此 ansi 代码略有不同。

标签: python regex cron rhel


【解决方案1】:

我遇到了完全相同的问题,只是在我的情况下,我运行“ifconfig -a”以从我的 python 脚本中包含的 Linux 服务器获取 IPv6 和 IPv4 信息。

从终端,正则表达式和控制台中打印的输出运行良好,但从 cron 作业执行时我得到“空白”。

所以,这就是解决方案:

在您的脚本中,您提供要执行的 bash 命令(在您的情况下,假设它是“top”)在我的情况下为“ifconfig -a”,您必须提供此应用程序/实用程序/的完整路径Linux 机器中的命令。

我有这个(错误):

import subprocess
ifconfig_command = "ifconfig -a"
run_ifconfig_command = subprocess.Popen(ifconfig_command,stdout=subprocess.PIPE,shell=True).stdout.read()

您应该使用命令的完整路径 (SUCCESSFUL):

import subprocess
ifconfig_command = "/usr/sbin/ifconfig -a"
run_ifconfig_command = subprocess.Popen(ifconfig_command,stdout=subprocess.PIPE,shell=True).stdout.read()

从现在开始,当我将它与 run_ifconfig_command 进行比较时,我的 RegEx 开始工作了

我知道这篇文章已经过去了 7 年,但我希望它可以帮助任何有这个或类似问题的人。

PD:对于任何命令或实用程序的完整路径,您可以使用:

which <*command or utility*>

并且它应该提供命令的安装文件夹的整个位置。

【讨论】:

    【解决方案2】:

    您看到的是 termcap 代码,用于根据所连接的显示设备类型显示内容。当您从 cron 运行该命令时,没有连接的设备。您的程序没有为您提供相同的数据。

    以下是获取相同数据的三种可能方式:

    1)也许,您可以设置终端环境变量,您的程序可能(!!)工作相同。这不太可能。在 cron "TERM=vt100OrSomething /pathtomyscript/myscript.py" 中。没有“导出”或分号或任何东西。

    2) 您可以在 screen 或 tmux 中分离运行它,并使用它们的终端仿真。或者,您可以使用 Expect 的“unbuffer”程序。您必须更改您的代码以匹配它为 tmux 的假终端发送的内容。

    3) 正常连接,并取消设置“TERM”环境变量,然后你会很像 cron 环境。不要尝试制作像交互式会话那样疯狂、未知的 cron 环境。使您的交互式会话像您的 cron 环境一样,并在那里解决它。

    在所有这些中,我认为你应该选择#3。启动子shell进行测试:

    $ vi program    
    $ bash    
    $ unset TERM; PS1=\$\$    
    $$ ./program    
    $$ exit    
    $ vi program    
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      相关资源
      最近更新 更多