手动 crontab 和 运行 脚本之间的不同结果
different results between crontab and running script manually
我有一个 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 用户的 运行,因此它具有扫描整个网络所需的所有提升。
首先,你的 grep 正则表达式有几个问题:
- 重复计数 (
{1,3}
) 适用于其前面的原子(即“.
”)而不是下一个(即“[0-9]
”)。
正则表达式中的一个未转义的点('.
')匹配任何字符,它隐藏了之前的错误。您的正则表达式 (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
正确的正则表达式必须是 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
您的脚本缺少 shebang,因此它可能 运行 具有不同的 shell,具体取决于 crontab 或手动启动。
在脚本的第一行添加以下内容(如果需要,将 bash 替换为当前用户 shell):
#!/usr/bin/env bash
不要使用 /bin/bash,因为它的便携性不如 /usr/bin/env bash。
此外,crontab 运行s 将没有 PATH 变量。
使用以下命令打印您的路径变量:
echo $PATH
并将其添加为脚本的第二行,例如:
#!/usr/bin/env bash
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin
这应该确保您的脚本 运行s 在与 运行 通过 crontab 或手动时相同的环境中。
我有一个 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 用户的 运行,因此它具有扫描整个网络所需的所有提升。
首先,你的 grep 正则表达式有几个问题:
- 重复计数 (
{1,3}
) 适用于其前面的原子(即“.
”)而不是下一个(即“[0-9]
”)。 正则表达式中的一个未转义的点('
.
')匹配任何字符,它隐藏了之前的错误。您的正则表达式 (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
正确的正则表达式必须是 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
您的脚本缺少 shebang,因此它可能 运行 具有不同的 shell,具体取决于 crontab 或手动启动。
在脚本的第一行添加以下内容(如果需要,将 bash 替换为当前用户 shell):
#!/usr/bin/env bash
不要使用 /bin/bash,因为它的便携性不如 /usr/bin/env bash。
此外,crontab 运行s 将没有 PATH 变量。 使用以下命令打印您的路径变量:
echo $PATH
并将其添加为脚本的第二行,例如:
#!/usr/bin/env bash
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin
这应该确保您的脚本 运行s 在与 运行 通过 crontab 或手动时相同的环境中。