编写shell脚本来安装cron作业

Em *_* Ae 9 linux bash shell cron

这是我第一次编写shell脚本,而且在给定的时间线中我的信息很少.虽然我正在阅读不同的教程,但我想在这里问我想要什么.

我想编写一个shell脚本,在任何机器上编辑cronjob,添加一个每15分钟执行一次的新脚本.所以基本上我必须添加一个条目

0,15,30,45 * * * * /home/personal/scripts/cronSqlprocedure.sh

我想要的shell脚本

  • 它首先会更改权限/执行权限 cronSqlprocedure.sh
  • 编辑现有的cron作业并将此新条目添加到其中.

如果可能的话,我也想通过shell脚本编写cronSqlprocedure,因为它需要几个变量,这些变量可能因系统而异.

export ORACLE_HOME=/opt/app/oracle/product/11.2.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
export ORACLE_SID=HEER
Run Code Online (Sandbox Code Playgroud)

必须为每台机器配置这些线路cronSqlprocedure.sh.

#!/bin/bash
ORACLE_HOME="/opt/app/oracle/product/11.2.0/dbhome_1"
ORACLE_SID="HEER"
ORACLE_USER="USER1"
ORACLE_PASSWORD="USERPASS"

echo "export ORACLE_HOME=$ORACLE_HOME" >> $PWD/sqlcronprocedure.sh
echo "export PATH=\$ORACLE_HOME/bin:\$PATH" >> $PWD/sqlcronprocedure.sh
echo "export ORACLE_SID=$ORACLE_SID" >> $PWD/sqlcronprocedure.sh
echo "rTmpDir=/tmp" >> $PWD/sqlcronprocedure.sh

echo "sqlplus -s $ORACLE_USER@$ORACLE_SID/$ORACLE_PASSWORD  > $rTmpDir/deleteme.txt 2>&1 <<EOF" >> $PWD/sqlcronprocedure.sh
echo "    select 1 from dual;" >> $PWD/sqlcronprocedure.sh
echo "    execute another_script(1000,14);" >> $PWD/sqlcronprocedure.sh
echo "EOF" >> $PWD/sqlcronprocedure.sh

chmod 755 $PWD/sqlcronprocedure.sh

crontab -l > $PWD/sqlcorn.sh
echo "0,15,30,45 * * * * $PWD/sqlcronprocedure.sh" >> $PWD/sqlcorn.sh
crontab $PWD/sqlcorn.sh
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 13

简单回答原始问题

这看起来像是常规的shell脚本:

# Clobber previous edition of script!
cronscript=$HOME/scripts/cronSqlprocedure.sh
cat <<EOF > $cronscript
export ORACLE_HOME=/opt/app/oracle/product/11.2.0/dbhome_1
export PATH=\$ORACLE_HOME/bin:\$PATH
export ORACLE_SID=HEER
...and whatever else is needed...
EOF
chmod u+x $cronscript

# Add to crontab
tmp=${TMPDIR:-/tmp}/xyz.$$
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
crontab -l | sed '/cronSqlprocedure.sh/d' > $tmp  # Capture crontab; delete old entry
echo "0,15,30,45 * * * * $cronscript" >> $tmp
crontab < $tmp
rm -f $tmp
trap 0
Run Code Online (Sandbox Code Playgroud)

trap如果用户决定中断,清理临时文件,这些东西可确保最小的损坏.请注意,旧版本的脚本(如果有)已被破坏.如果你愿意,你可以安排将脚本创建到另一个临时文件中,只有在满意时才完成移动.我通常在crontab命令上使用I/O重定向; 你可以很好地提供文件名作为参数.

需要注意的逃逸\$ORACLE_HOME\$PATH那个威廉Pursell正确地指出,应该出现在\$ORACLE_HOME和应(也许)存在的\$PATH.您需要决定是否要使用 - 提供cron(完全最小)值$PATH(在这种情况下您需要反斜杠)或者是否要$PATHcron脚本中使用用户的当前值.两者都可能是正确的 - 只要知道你选择哪个以及为什么.请记住,提供的环境cron总是很少; 您将获得PATH,HOME,也许是TZ的设置,可能是USER和可能的LOGNAME; 这可能就是全部.如果您不确定,请尝试运行crontab条目,该条目捕获文件中的环境:

* * * * * env > /tmp/cron.env
Run Code Online (Sandbox Code Playgroud)

你可能会发现文件很小.测试后不要忘记删除条目.

你应该受到赞扬的一件好事:

  • 您的脚本(a)确保它设置环境,并(b)从crontab条目运行一个简单的命令,让脚本完成艰苦的工作.

在我看来,crontab文件中的条目确实应该像这样简单,调用专用脚本来完成实际工作.


修订问题中对拟议脚本的批判

#!/bin/bash
ORACLE_HOME="/opt/app/oracle/product/11.2.0/dbhome_1"
ORACLE_SID="HEER"
ORACLE_USER="USER1"
ORACLE_PASSWORD="USERPASS"
Run Code Online (Sandbox Code Playgroud)

到目前为止,没问题:

echo "export ORACLE_HOME=$ORACLE_HOME" >> $PWD/sqlcronprocedure.sh
echo "export PATH=\$ORACLE_HOME/bin:\$PATH" >> $PWD/sqlcronprocedure.sh
echo "export ORACLE_SID=$ORACLE_SID" >> $PWD/sqlcronprocedure.sh
echo "rTmpDir=/tmp" >> $PWD/sqlcronprocedure.sh

echo "sqlplus -s $ORACLE_USER@$ORACLE_SID/$ORACLE_PASSWORD  > $rTmpDir/deleteme.txt 2>&1 <<EOF" >> $PWD/sqlcronprocedure.sh
echo "    select 1 from dual;" >> $PWD/sqlcronprocedure.sh
echo "    execute prvsapupd(1000,14);" >> $PWD/sqlcronprocedure.sh
echo "EOF" >> $PWD/sqlcronprocedure.sh
Run Code Online (Sandbox Code Playgroud)

这是非常重复的,从附加开始并不好.我会用:

cronscript=$PWD/sqlcronprocedure.sh
{
echo "export ORACLE_HOME=$ORACLE_HOME"
echo "export PATH=\$ORACLE_HOME/bin:\$PATH"
echo "export ORACLE_SID=$ORACLE_SID"
echo "rTmpDir=/tmp"

echo "sqlplus -s $ORACLE_USER@$ORACLE_SID/$ORACLE_PASSWORD  > $rTmpDir/deleteme.txt 2>&1 <<EOF"
echo "    select 1 from dual;"
echo "    execute prvsapupd(1000,14);"
echo "EOF"
} > $cronscript
Run Code Online (Sandbox Code Playgroud)

{ ... }应用I/O重定向到封闭的命令.请注意,之前必须有分号或换行符}.

chmod 755 $PWD/sqlcronprocedure.sh
Run Code Online (Sandbox Code Playgroud)

由于我有一个文件名变量,我会用它:

chmod 755 $cronscript
Run Code Online (Sandbox Code Playgroud)

然后我们在这里有重复的问题,而不是在我们身后清理:

crontab -l > $PWD/sqlcorn.sh
echo "0,15,30,45 * * * * $PWD/sqlcronprocedure.sh" >> $PWD/sqlcorn.sh
crontab $PWD/sqlcorn.sh
Run Code Online (Sandbox Code Playgroud)

因此,我写道:

crontab=sqlcron.sh
crontab -l > $crontab
echo "0,15,30,45 * * * * $cronscript" >> $crontab
crontab $crontab
rm -f $crontab
Run Code Online (Sandbox Code Playgroud)

我仍然认为这trap不是太难,应该在任何创建临时文件的脚本中使用; 然而,这是你的烂摊子,不是我的.我不相信$PWD到处都需要它; 我把它留在一个名字而不是另一个名字.如果您不提供目录路径,$PWD则暗示.我还注意到,您在建议的完整脚本中使用的脚本名称与原始脚本名称略有不同.只要名称是自洽的,就没有问题(使用变量有助于确保一致性),但要小心.

我不确定我是否真的这样做,但你也可以避免使用临时文件:

{
crontab -l
echo "0,15,30,45 * * * * $cronscript"
} | (sleep 1; crontab -)
Run Code Online (Sandbox Code Playgroud)

这将收集当前值并附加额外的行,将所有这些内容提供给脚本,该脚本在将结果反馈之前休眠一秒钟(允许第一部分时间完成)crontab.有一个问题是主要是一秒延迟的可靠性.这可能很好,但不能保证.临时文件是100%可靠的 - 我会使用它,因为它不再复杂.(我可以在第一对命令周围使用括号;我可以在第二对命令周围使用大括号,但是我需要在它之间添加一个分号,-然后)替换为}.)

请注意,我的原始提案小心确保即使脚本多次运行,crontab文件中也只有一个条目用于该过程.您的变体无法确保幂等性.