Пишу скрипт для установки хрон

Это первый раз, когда я пишу скрипт, и у меня очень мало информации в заданные сроки. Хотя я читаю разные учебники, но я подумал спросить, что я хочу здесь.

Я хочу написать сценарий оболочки, который на любой машине, отредактируйте cronjob, добавьте новый скрипт, который будет выполняться каждые 15 минут. поэтому в основном я должен добавить запись

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

то, что я хочу в оболочке скрипт

  • сначала он изменит права доступа / выполнения для cronSqlprocedure.sh
  • редактировать существующее задание cron и добавьте в него эту новую запись.

если возможно, я хотел бы написать 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

4 ответов


простой ответ на оригинальный вопрос

все это похоже на рутинные сценарии оболочки:

# 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 command; вы можете отлично указать имя файла в качестве аргумента.

обратите внимание на побеги на $ORACLE_HOME и $PATH это Уильям Pursell правильно указал на $ORACLE_HOME и должен (может) присутствовать на $PATH. Вам нужно решить, хотите ли вы взять cron - при условии (полностью минимальное) значение $PATH (в этом случае вы хотите обратную косую черту) или хотите ли вы использовать текущее значение пользователя $PATH в cron сценарий. Любой из них может быть правильным - просто знайте, какой вы выбираете и почему. Помните, что среда, предоставляемая cron всегда минимально; вы получите настройку для PATH, HOME, возможно, TZ, вероятно, USER и, возможно, LOGNAME; это может быть все. Если вы не уверены, попробуйте запустить запись crontab, которая захватывает среду в файле:

* * * * * env > /tmp/cron.env

вы, вероятно, обнаружите, что файл небольшой. Не забудьте удалить запись после тестирования.

один хорошо, что вы заслуживаете похвалы:

  • ваш скрипт (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"

до сих пор, никаких проблем:

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

это ужасно повторяется, и начинать с append нехорошо. Я бы использовал:

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

на { ... } примените перенаправление ввода-вывода к вложенным командам. Обратите внимание, что перед }.

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 для процесса. Ваши варианты не гарантируют идемпотентности.


Я нашел аналогичный вопрос:программно отредактируйте crontab и заставьте демона обновить

изменение разрешений файла является типичным сценарием оболочки со многими доступными ресурсами.

для cronjob вы захотите по существу взаимодействовать с программой crontab и кормить ее и совершенно новый файл cron. Вы можете сначала получить уже настроенные задания cron, добавить свои в список, а затем снова вызвать crontab, чтобы дать ему новый ввод файл.

смотрите man-page для кронтаб для получения дополнительной информации.


#!/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

создать 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:

Я бы рекомендовал использовать /etc/cron.d над crontab.

вы можете разместить файлы в /etc/cron.d которые ведут себя, как с помощью crontab. Хотя формат немного отличается.

Патрик указывает, что это может не работать на всех системах, но его ответ принимается и имеет большинство голосов. Он хорошо работает для меня на debian 9 (stretch).

источник: https://unix.stackexchange.com/questions/117244/installing-crontab-using-bash-script#117254