[英]Writing a shell script to install cron job
这是我第一次编写shell脚本,而且在给定的时间线中我的信息很少。 虽然我正在阅读不同的教程,但我想在这里问我想要什么。
我想编写一个shell脚本,在任何机器上编辑cronjob,添加一个每15分钟执行一次的新脚本。 所以基本上我必须添加一个条目
0,15,30,45 * * * * /home/personal/scripts/cronSqlprocedure.sh
我想要的shell脚本
cronSqlprocedure.sh
的权限/执行权限 如果可能的话,我也想通过shell脚本编写cronSqlprocedure,因为它需要几个变量,这些变量可能因系统而异。
export ORACLE_HOME=/opt/app/oracle/product/11.2.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
export ORACLE_SID=HEER
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
这看起来像是常规的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
如果用户决定中断,清理临时文件, trap
内容可确保最小的损坏。 请注意,旧版本的脚本(如果有)已被破坏。 如果你愿意,你可以安排将脚本创建到另一个临时文件中,只有在满意时才完成移动。 我通常在crontab
命令上使用I / O重定向; 你可以很好地提供文件名作为参数。
注意William Pursell正确指出的\\$ORACLE_HOME
和\\$PATH
上的转义应该出现在\\$ORACLE_HOME
并且应该(或许)出现在\\$PATH
。 您需要决定是否要使用$PATH
的cron
(完全最小的)值(在这种情况下,您需要反斜杠),或者是否要在cron
脚本中使用用户当前的$PATH
值。 两者都可能是正确的 - 只要知道你选择哪个以及为什么。 请记住, cron
提供的环境总是很少; 您将获得PATH,HOME,也许是TZ的设置,可能是USER和可能的LOGNAME; 这可能就是全部。 如果您不确定,请尝试运行crontab条目,该条目捕获文件中的环境:
* * * * * env > /tmp/cron.env
你可能会发现文件很小。 测试后不要忘记删除条目。
你应该受到赞扬的一件好事:
crontab
条目运行一个简单的命令,让脚本完成艰苦的工作。 在我看来, crontab
文件中的条目确实应该像这样简单,调用专用脚本来完成实际工作。
#!/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 prvsapupd(1000,14);" >> $PWD/sqlcronprocedure.sh
echo "EOF" >> $PWD/sqlcronprocedure.sh
这是非常重复的,从附加开始并不好。 我会用:
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
{ ... }
将I / O重定向应用于所附的命令。 请注意, }
之前必须有分号或换行符。
chmod 755 $PWD/sqlcronprocedure.sh
由于我有一个文件名变量,我会用它:
chmod 755 $cronscript
那么我们在这里有重复的问题,而不是在我们身后清理:
crontab -l > $PWD/sqlcorn.sh
echo "0,15,30,45 * * * * $PWD/sqlcronprocedure.sh" >> $PWD/sqlcorn.sh
crontab $PWD/sqlcorn.sh
因此,我写道:
crontab=sqlcron.sh
crontab -l > $crontab
echo "0,15,30,45 * * * * $cronscript" >> $crontab
crontab $crontab
rm -f $crontab
我仍然认为trap
不是太难,应该在任何创建临时文件的脚本中使用; 然而,这是你的烂摊子,不是我的。 我不相信到处都需要$PWD
; 我把它留在一个名字而不是另一个名字。 如果您不提供目录路径,则隐含$PWD
。 我还注意到,您在建议的完整脚本中使用的脚本名称与原始脚本名称略有不同。 只要名称是自洽的,就没有问题(使用变量有助于确保一致性),但要小心。
我不确定我是否真的这样做,但你也可以避免使用临时文件:
{
crontab -l
echo "0,15,30,45 * * * * $cronscript"
} | (sleep 1; crontab -)
这将收集当前值并附加额外的行,将所有内容提供给脚本,该脚本在将结果反馈回crontab
之前休眠一秒钟(允许第一部分时间完成)。 有一个问题是主要是一秒延迟的可靠性。 这可能很好,但不能保证。 临时文件是100%可靠的 - 我会使用它,因为它不再复杂。 (我可以使用围绕所述第一对命令的括号;我可以使用周围的第二对命令的牙套,但我需要添加之间分号-
和)
由取代}
)。
请注意,我的原始提案小心确保即使脚本多次运行,crontab文件中也只有一个条目用于该过程。 您的变体无法确保幂等性。
创建一个cron.d文件,例如/etc/cron.d/my-sql-proc
0,15,30,45 * * * * root /home/personal/scripts/cronSqlprocedure.sh
#
# run-as user
通过@Patrick从unix.stackexchange.com答案:
我建议在
crontab
使用/etc/cron.d
。您可以将文件放在
/etc/cron.d
,其行为类似于crontab条目。 虽然格式略有不同。
帕特里克指出它可能不适用于所有系统,但他的答案既被接受又获得最多票数。 它在debian 9(拉伸)上对我很有用。
来源: https : //unix.stackexchange.com/questions/117244/installing-crontab-using-bash-script#117254
我发现了一个类似的问题:以编程方式编辑crontab并强制守护进程刷新
更改文件的权限是典型的shell脚本,有许多可用资源。
对于cronjob,你将基本上与crontab程序接口并提供它和全新的cron文件。 您可以先检索已配置的cron作业,将其添加到列表中,然后再次调用crontab为其提供新的输入文件。
有关更多信息,请参阅crontab的手册页。
#!/bin/sh SCRIPT=/home/personal/scripts/cronSqlprocedure.sh # write the script. cat > $SCRIPT << 'EOF' export ORACLE_HOME=/opt/app/oracle/product/11.2.0/dbhome_1 export PATH=$ORACLE_HOME/bin:$PATH export ORACLE_SID=HEER EOF # Make the script executable chmod +x $SCRIPT # Add this script to the existing crontab. This relies on your # sed supporting -i. if it does not, it is probably easiest to # write a simple script that does the edit and set VISUAL to that script if ! crontab -l | grep $SCRIPT > /dev/null; then VISUAL='sed -i -e "\$a\ 0,15,30,45 * * * * '$SCRIPT'"' crontab -e fi
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.