crontab和手动运行脚本之间的不同结果

时间:2016-09-13 21:53:22

标签: bash cron network-programming nmap

我有一个执行此操作的bash脚本:

nmap -sn 192.168.0.1-255 | grep -Eo 192.168.0.{1,3\}[0-9] > new.txt
date >> network_log
echo ---------------------------- >> network_log
cat new.txt >> network_log

扫描网络,并将结果附加到带有时间戳的文件network_log。 手动运行后,network_log文件如下所示:

Tue 13 Sep 2016 11:22:23 EDT 
---------------------------- 

192.168.0.1
192.168.0.2 
192.168.0.45

而cronjobs在我的network_log文件中产生以下输出:

Tue Sep 13 17:46:00 EDT 2016
----------------------------

没有ip结果。 注意:cronjob从root用户运行,因此它具有扫描整个网络所需的所有高程。

2 个答案:

答案 0 :(得分:1)

首先,你的grep正则表达式中有几个问题:

  1. 重复次数({1,3})适用于其前一个原子(即' .')而不是下一个原子(即' [0-9] '。)
  2. 正则表达式中未转义的点(' .')匹配任何隐藏上一个错误的字符。您的正则表达式(192.168.0.{1,3}[0-9])与192.168.0.123匹配,如下所示:

    192.168.0 matches 192.168.0
    .{1,3}    matches .12
    [0-9]     matches 3
    

    但它也会匹配以下字符串:

    192116810abc1
    192.681.012.9
    
  3. 正确的正则表达式必须是192\.168\.0\.[0-9]{1,3}并且必须引用它,以便bash将字面意思传递给grep:

    grep -Eo '192\.168\.0\.[0-9]{1,3}'
    

    然而,错误的正则表达式很难解释你在cron中遇到的问题。

    一个问题可能是您使用固定名称new.txt作为临时文件。如果您在其他脚本中执行相同的操作,或者将此cron作业设置为每分钟运行一次,而nmap超过一分钟才能完成扫描网络,则new.txt可能会被覆盖错误的时间。

    请按照以下方式修改脚本并检查问题是否消失:

    #!/bin/bash
    
    tmpfile="$(mktemp)"
    trap "rm $tmpfile" EXIT
    nmap -sn 192.168.0.1-255 | grep -Eo '192\.168\.0\.[0-9]{1,3}' > "$tmpfile"
    date >> network_log
    echo ---------------------------- >> network_log
    cat "$tmpfile" >> network_log
    

答案 1 :(得分:1)

你的脚本缺少一个shebang,所以它可能会运行不同的shell,具体取决于crontab或手动启动。

在脚本中添加以下内容作为第一行(如果需要,将bash替换为当前用户shell):

#!/usr/bin/env bash

不要使用/ bin / bash,因为它的可移植性不如/ usr / bin / env bash。

此外,crontab运行没有PATH变量。 使用以下命令打印路径变量:

echo $PATH

并将其添加为脚本的第二行,如:

#!/usr/bin/env bash
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin

这应该确保您的脚本在由crontab运行或手动运行时在同一环境中运行。