在bash脚本

时间:2018-06-07 18:45:45

标签: bash ubuntu cron

我遇到了一些严重问题,试图为我的bash脚本获取正确的格式,以便能够在crontab中成功运行。从命令行手动提示时,bash脚本成功运行。 这是有问题的bash脚本(实际参数本身[$ 1& $ 2]已手动放入脚本中):

#!/bin/bash
# Usage: ./s3DeleteByDateVirginia "bucketname" "file type"

past=$(date +"%F" -d "60 days ago")

aws s3api list-objects --bucket $1 --query 'Contents[?LastModified<=`'$past'`][].{Key:Key}' | grep $2 | while read -r line
do
fileName=`echo $line`
aws s3api delete-object  --bucket $1 --key "$fileName"
done;

脚本在这个bash文件中:/ home / ubuntu / s3DeleteByDateVirginiaSoco1 要设置我使用的脚本:sudo crontab -e 现在我看到网上的人说你需要给它一个对我没有任何意义的正确路径,特别是当它把它放在正确的位置因为我看到这个在线的各种修改但它包括这种格式:SHELL = / bin / sh sPATH = / bin:/ sbin:/ usr / bin:/ usr / sbin但我不知道放在哪里。

根据syslog,部分工作但脚本本身不执行的cron功能:syslog

除此之外,脚本还具有所有正确的权限。 总而言之,我更困惑的是,当我开始时,我没有看到关于crontab如何工作的那么多文档。

有问题的Crontab:enter image description here

根据用户的建议进行其他修改:   这是我的优秀脚本: enter image description here

这是crontab行:

 # m h  dom mon dow   command

PATH=/usr/local/bin:/usr/bin:/bin:/root/.local/bin/aws
33 20 * * *  /home/ubuntu/s3DeleteByDateSoco1

更新了syslog: enter image description here

1 个答案:

答案 0 :(得分:1)

好的,我在这里看到了几个问题。首先,您需要将此文件放在您希望脚本运行的用户的crontab文件中。如果您想在用户帐户下运行它,请不要仅使用crontab -e而不是sudo crontab -e(使用sudo,它会编辑root用户的crontab文件。)

其次,你需要使用正确的路径&amp;脚本的名称;它看起来像是/home/ubuntu/s3DeleteByDateVirginiaSoco1,所以这就是crontab条目中的内容。如果它实际上不是文件名的一部分,请不要添加“.sh”。它看起来像你尝试在路径前添加“root”;不要这样做,因为crontab将尝试执行“root”作为命令,它将失败。 bash -c没有伤害,但它根本没有帮助,所以不要使用它。

第三,需要为脚本中使用的可执行文件正确设置PATH。默认情况下,cron作业使用PATH只执行“/ usr / bin:/ bin”,因此当您使用aws之类的命令时,它会将其查找为/usr/bin/aws,而不是找到它,将其查找为/usr/aws,找不到它,并在上一个日志条目中显示错误“aws:command not found”。首先,您需要找出aws(以及您的脚本所依赖的任何其他程序)的位置;您可以在常规shell中使用which aws来查找它。假设它是/ usr / local / bin / aws。然后你可以:

  • 在crontab文件之前添加一行PATH=/usr/local/bin:/usr/bin:/bin(可能是您认为合适的任何其他目录),然后表示运行脚本的行。

  • 在您的脚本文件之前添加一行PATH=/usr/local/bin:/usr/bin:/bin(可能是您认为合适的任何其他目录)使用aws的行。

  • 在您的脚本中,每次要运行aws时都会使用显式路径(类似/usr/local/bin/aws s3api list-objects ...

您可以使用上述任何(或全部),但您必须使用至少一个,否则将无法找到aws命令(或其他任何不在OS附带的核心命令。

第四,我没有看到提供$1$2的位置。你说他们已被手动放在脚本中,但我不知道你的意思。由于脚本期望它们作为参数,您需要在crontab文件中指定它们(即crontab中的命令应该类似于/home/ubuntu/s3DeleteByDateVirginiaSoco1 bucketname pattern)。

第五,脚本本身并不遵循良好的引用约定。通常,所有变量引用都应该是双引号。例如,使用grep "$2"代替grep $2。如果没有双引号,包含空格或某些shell元字符的变量可能会导致奇怪的解析问题。

最后,你为什么要做fileName=echo $line(带反引号我不能在这里复制)?这主要只是将$line的值复制到变量fileName中,但可能会出现我在上一点提到的那些奇怪的解析问题。如果您想要可靠地复制变量,只需使用fileName="$line"(或fileName=$line - 这是少数可以安全地保留双引号的情况之一。

BTW,shellcheck.net善于发现不良引用等常见问题;我建议您通过它运行脚本以查看它找到的内容。