使用 bash 脚本更新 CRON

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17267904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:45:51  来源:igfitidea点击:

Updating CRON with bash script

linuxbashsedcrontab

提问by Atomiklan

Can anyone see my syntax error here? Trying to edit/update a cron job, but the file is not being updated.

谁能在这里看到我的语法错误?尝试编辑/更新 cron 作业,但文件未更新。

crontab -l | sed 's%*/5 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh%*/10 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh%' | crontab -

* UPDATE *

* 更新 *

So im still having trouble with this. Ultimately I am trying to pull a value from a config file $FREQ (minutes) to run the job. The script will first check to see if the value in the config is different than the value currently in the crontab. If the value is different, it will update the crontab with the new value. The crontab (both initial install and updates) also pulls the running directory and script name from variables. Example:

所以我仍然有这个问题。最终,我试图从配置文件 $FREQ(分钟)中提取一个值来运行该作业。该脚本将首先检查配置中的值是否与 crontab 中的当前值不同。如果值不同,它将用新值更新 crontab。crontab(初始安装和更新)还从变量中提取运行目录和脚本名称。例子:

DIR=`pwd`
SCRIPT=`basename 
function CRON {
  if [ "`crontab -l | grep $SCRIPT`" \> " " ]; then
    CTMP=$(crontab -l | grep $SCRIPT)
    if [ "$CTMP" = "*/$FREQ * * * * cd $DIR && ./$SCRIPT" ]; then
      echo "$GREEN No modifications detected $RESET"
    else
      crontab -l | "sed s%$CTMP%*/$FREQ * * * * cd $DIR && ./$SCRIPT%" | crontab -
    fi
  else
    echo "$YELLOW CRON not detected - Installing defaults $RESET"
    (crontab -l ; echo "*/$FREQ * * * * cd $DIR && ./$SCRIPT") | crontab -
  fi
}
` CRONTMP=`crontab -l | grep anm.sh` crontab -l | sed 's%'$CTMP'%*/'$FREQ' * * * * cd '$DIR' && ./'$SCRIPT'%' | crontab -

Something along those lines. Obviously this is missing a few things, but that should give you the general idea.

沿着这些路线的东西。显然这遗漏了一些东西,但这应该给你一个大致的想法。

Thanks for the help!

谢谢您的帮助!

* UPDATE *

* 更新 *

Ok so things are moving along, but I am still having one tiny problem. I think I have most of the logic worked out. Here is the entire (pertinent) part of the script so you can get a feel for exactly what I am trying to accomplish.

好的,事情正在进展,但我仍然有一个小问题。我想我已经解决了大部分逻辑。这是脚本的整个(相关)部分,因此您可以准确了解我正在尝试完成的工作。

Remember: $SCRIPT and $DIR are defined outside the function and are just equal to the scripts name (anm.sh for example), and the current working directory. And I took your suggestion and updated all my code. I now use SCRIPT=$(basename $0). Thanks

请记住:$SCRIPT 和 $DIR 是在函数外部定义的,它们与脚本名称(例如 anm.sh)和当前工作目录相同。我接受了你的建议并更新了我的所有代码。我现在使用 SCRIPT=$(basename $0)。谢谢

CTMP=$(crontab -l | grep $SCRIPT)

Essentially, when the function runs, it first checks to see if the cron job is even installed (perhaps this is the first time the script has run). If it doesn't detect anything, it appends the cron job to the crontab file. This works great so far. Next, if the function does detect that the cron job has been installed, it compares it vs the frequency (in minutes) set in the configuration file. If they are the same, no modification has been made to the config file and the script moves on. Lastly, if the values are indeed different, it then tries to update the corresponding line in the crontab file to reflect the changes made in the configuration file. This last part fails. Currently its just overwriting the crontab file completely to blank.

本质上,当函数运行时,它首先检查是否安装了 cron 作业(也许这是脚本第一次运行)。如果它没有检测到任何内容,它会将 cron 作业附加到 crontab 文件中。到目前为止,这很好用。接下来,如果该函数确实检测到已安装 cron 作业,则会将其与配置文件中设置的频率(以分钟为单位)进行比较。如果它们相同,则未对配置文件进行任何修改,脚本继续运行。最后,如果值确实不同,它会尝试更新 crontab 文件中的相应行以反映在配置文件中所做的更改。这最后一部分失败了。目前它只是将 crontab 文件完全覆盖为空白。

* UPDATE *

* 更新 *

It looks like there is a major issue with the following line. This is not properly pulling the desired line out of the crontab and storing it to the variable CTMP:

以下行似乎存在重大问题。这没有正确地从 crontab 中拉出所需的行并将其存储到变量 CTMP:

sed s%*/12 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh%*/10 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh%: No such file or directory

when I echo out CTMP, I get a bunch of unexpected results. Apparently I am using grep incorrectly here.

当我回显 CTMP 时,我得到了一堆意想不到的结果。显然我在这里错误地使用了grep。

Ok this issue was resolved. The variable was being stored correctly, I was just echoing it out incorrectly.

好的,这个问题解决了。变量被正确存储,我只是错误地回应了它。

* UPDATE 06/24/13 5:08am *

* 更新 06/24/13 5:08am *

The last issue seems to be the sed line. Here is the error message I am researching now.

最后一个问题似乎是 sed 行。这是我现在正在研究的错误消息。

function CRON {
  if [ "`crontab -l | grep $SCRIPT`" \> " " ]; then
    CTMP="$(set -f; crontab -l | grep $SCRIPT)"
    if [ "$CTMP" = "*/$FREQ * * * * cd $DIR && ./$SCRIPT" ]; then
      echo "$GREEN No modifications detected $RESET"
    else
      crontab -l | sed "s%$CTMP%*/$FREQ * * * * cd $DIR && ./$SCRIPT%" | crontab -
    fi
  else
    echo "$YELLOW CRON not detected - Installing defaults $RESET"
    (crontab -l ; echo "*/$FREQ * * * * cd $DIR && ./$SCRIPT") | crontab -
  fi
}

It looks like it's trying to replace the line, but failing.

看起来它正在尝试更换线路,但失败了。

* UPDATE 06/24/13 5:45am *

* 更新 06/24/13 5:45am *

So the error message above was ofcourse caused by my own stupidity. I was including sed inside the quotes. I have since removed the command from the quotes, however the issue still persists. I have tried single quotes, double quotes, escaping * and . with no luck. The cron file is still not updating. Here is the current code:

所以上面的错误信息当然是我自己的愚蠢造成的。我在引号中包含了 sed 。我已经从引号中删除了命令,但是问题仍然存在。我试过单引号、双引号、转义 * 和 . 没有运气。cron 文件仍未更新。这是当前的代码:

CTMPESC=$(sed 's/[\*\.&]/\&/g' <<<"$CTMP")
DIRESC=$(sed 's/[\*\.&]/\&/g' <<<"$DIR")
SCRIPTESC=$(sed 's/[\*\.&]/\&/g' <<<"$SCRIPT")
crontab -l | sed "s%$CTMPESC%\*/$FREQ \* \* \* \* cd $DIRESC \&\& \./$SCRIPTESC%" | crontab -

* UPDATE 06/24/13 6:05am *

* 更新 06/24/13 6:05am *

Perhaps the issue is I'm not escaping everything. ie, the variables inside the sed expression once expanded have characters that need escaping? Could that be the issue? If so, im not exactly sure how to resolve this. Please help.

也许问题是我没有逃避一切。即,sed 表达式中的变量一旦展开就具有需要转义的字符?这可能是问题吗?如果是这样,我不确定如何解决这个问题。请帮忙。

* SOLVED *

* 解决了 *

I did indeed have to escape the variables as well before passing them to sed. Here is the code:

在将变量传递给 sed 之前,我确实也必须对其进行转义。这是代码:

CTMPESC=$(sed 's/[\*\.&]/\&/g' <<<"$CTMP")
DIRESC=$(sed 's/[\*\.&]/\&/g' <<<"$DIR")
SCRIPTESC=$(sed 's/[\*\.&]/\&/g' <<<"$SCRIPT")
crontab -l | sed "s%$CTMPESC%\*/$FREQ \* \* \* \* cd $DIRESC \&\& \./$SCRIPTESC%" | crontab -

采纳答案by Atomiklan

* SOLVED *

* 解决了 *

I did indeed have to escape the variables as well before passing them to sed. Here is the code:

在将变量传递给 sed 之前,我确实也必须对其进行转义。这是代码:

crontab -l | sed 's%\*/5 \* \* \* \* cd /home/administrator/anm-1\.5\.0 && \./anm\.sh%*/10 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh%' | crontab -

回答by jaypal singh

Try escaping the *and .in your substitution portion.

尝试在替换部分中转义*.

crontab -l | sed '/anm\.sh/s,^\*/5,*/10,' | crontab -

or, you can put in a regexthat matches your job and just change the timing

或者,您可以输入regex与您的工作相匹配的内容,然后更改时间

crontab -l | sed '/cd /s#\/5#\/10#' | crontab -

回答by icedwater

I would offer this shorter version:

我会提供这个较短的版本:

crontab -l | sed '/anm\.sh/s#\/5#\/10#' | crontab -

which should change 5 to 10 where the line has cd. Or use anm.shin place of cdas an address to be more specific in case there is more than one cdline:

应该将 5 更改为 10,其中该行具有cd. 或者anm.shcd有不止cd一行的情况下使用代替作为更具体的地址:

##代码##