crontab 和手动运行脚本的结果不同
Posted
技术标签:
【中文标题】crontab 和手动运行脚本的结果不同【英文标题】:different results between crontab and running script manually 【发布时间】:2017-01-21 14:50:15 【问题描述】:我有一个执行此操作的 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 用户运行的,因此它具有扫描整个网络所需的所有高度。
【问题讨论】:
您是否使用sudo
尝试过您的脚本,看看是cron 用户还是root 用户产生了影响?
我实际上是从 sudo cron 和常规 cron 运行脚本,它们都产生了相同的错误输出。我使用 sudo 和常规模式手动运行了我的脚本,它们产生了相同的正确输出。
检查环境变量差异。我会做grep -Eo '192\.168\.0\.1,3\[0-9]'
(引用)
尝试尝试...由于某种原因出现此错误:“grep: invalid repeat count(s)”
你还有其他写给new.txt
的cronjobs吗?
【参考方案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 或手动运行时在相同的环境中运行。
【讨论】:
谢谢!它现在可以工作了,你能给我提供一个链接或扩展为什么 /bin/bash 不如 /usr/bin/env bash 可移植 /bin/bash 是特定于 linux 的,而 /usr/bin/env 应该存在于所有 unix 系统上。请参阅***.com/questions/16365130/… 了解更多信息。【参考方案2】:首先,你的 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
【讨论】:
感谢所有这些建议,我从来没有意识到 tmpfile 的东西要好得多,尤其是因为 nmap 确实需要相对较长的时间来运行。并感谢您的正则表达式更正以上是关于crontab 和手动运行脚本的结果不同的主要内容,如果未能解决你的问题,请参考以下文章