Bash脚本手动运行正常,但从cron不完全运行。

huangapple go评论58阅读模式
英文:

Bash script runs fine when run manually, but doesn't fully run from cron

问题

以下是您提供的Bash脚本的翻译部分:

#!/bin/bash
pidof Overseer &>/dev/null
if [[ $? -ne 0 ]] ; then
    echo "重新启动 Overseer:$(date)" >> /mnt/drive/Bots/Overseer/Log.txt
    /mnt/drive/Bots/Overseer/Overseer >> /mnt/drive/Bots/Overseer/BotLog.txt
else
    echo "无需采取任何操作。$(date)" >> /mnt/drive/Bots/Overseer/Log.txt
fi

这是您的crontab文件的翻译部分:

# 编辑此文件以添加要由cron运行的任务。
# 每个要运行的任务都必须通过单行进行定义,指示任务将在何时运行的不同字段
# 以及任务的命令是什么。
# 要定义时间,可以为分钟(m)、小时(h)、月份中的日期(dom)、月份(mon),
# 以及星期中的日期(dow)提供具体的值,或在这些字段中使用"*"(表示“任意”)。
# 请注意,任务将根据cron系统守护程序对时间和时区的理解而启动。
# cron表中的作业的输出(包括错误)将通过电子邮件发送到cron文件所属的用户(除非重定向)。
# 例如,您可以在每周的5点运行备份所有用户帐户:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 有关更多信息,请参阅crontab(5)和cron(8)的手册页面
# m h  dom mon dow   command
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
* * * * * /mnt/drive/Bots/Overseer/startOverseer.sh >> /mnt/drive/Bots/Overseer/CronLog.txt 2>&1

CronLog.txt文件中的输出翻译如下:

未处理的异常。Microsoft.Data.Sqlite.SqliteException(0x80004005):SQLite错误1:'没有这个表:Settings'。
   在Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
   在Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements(Stopwatch timer)+MoveNext()
   在Microsoft.Data.Sqlite.SqliteCommand.GetStatements(Stopwatch timer)+MoveNext()
   在Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   在Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   在Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior behavior)
   在System.Data.Common.DbCommand.ExecuteReader()
   在Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   在Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(Enumerator enumerator)
   在Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.<>c.<MoveNext>b__21_0(DbContext _, Enumerator enumerator)
   在Microsoft.EntityFrameworkCore.Storage.NonRetryingExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   在Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
   在System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Boolean& found)
   在lambda_method23(Closure , QueryContext )
   在Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   在Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   在System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
   在Microsoft.EntityFrameworkCore.Internal.EntityFinder`1.Find(Object[] keyValues)
   在Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Find(Object[] keyValues)
   在Overseer.PteroWS..ctor(String SelectedServer) in C:\Users\ramor\Documents\GitHub\Overseer\Overseer\PteroWS.cs:line 29
   在Overseer.Program..ctor() in C:\Users\ramor\Documents\GitHub\Overseer\Overseer\Program.cs:line 19
   在Overseer.Program.Main() in C:\Users\ramor\Documents\GitHub\Overseer\Overseer\Program.cs:line 14
   在Overseer.Program.<Main>()
/mnt/drive/Bots/Overseer/startOverseer.sh: line 8: 31192 Aborted                 /mnt/drive/Bots/Overseer/Overseer >> /mnt/drive/Bots/Overseer/BotLog.txt

希望这有助于解决您的问题。如果您需要进一步的帮助,请随时提问。

英文:

I have the following bash script to check if a process is running, and if not, to restart it:

#!/bin/bash
pidof  Overseer &gt;/dev/null
if [[ $? -ne 0 ]] ; then
        echo &quot;Restarting Overseer:     $(date)&quot; &gt;&gt; /mnt/drive/Bots/Overseer/Log.txt
        /mnt/drive/Bots/Overseer/Overseer &gt;&gt; /mnt/drive/Bots/Overseer/BotLog.txt
else
    echo &quot;No action necessary.     $(date)&quot; &gt;&gt; /mnt/drive/Bots/Overseer/Log.txt
fi

If I open this manually, it starts Overseer fine and I get all the logs perfectly fine.

However, if cron runs this script, Overseer doesn't start and in Log.txt it says it was restarting.
I tried googling and saw suggestions to put the PATH variable into the crontab.

# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use &#39;*&#39; in these fields (for &#39;any&#39;).
# 
# Notice that tasks will be started based on the cron&#39;s system
# daemon&#39;s notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
* * * * * /mnt/drive/Bots/Overseer/startOverseer.sh &gt;&gt; /mnt/drive/Bots/Overseer/CronLog.txt 2&gt;&amp;1

Output in the CronLog.txt file:

Unhandled exception. Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: &#39;no such table: Settings&#39;.
   at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
   at Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements(Stopwatch timer)+MoveNext()
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements(Stopwatch timer)+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader()
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(Enumerator enumerator)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.&lt;&gt;c.&lt;MoveNext&gt;b__21_0(DbContext _, Enumerator enumerator)
   at Microsoft.EntityFrameworkCore.Storage.NonRetryingExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Boolean&amp; found)
   at lambda_method23(Closure , QueryContext )
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
   at Microsoft.EntityFrameworkCore.Internal.EntityFinder`1.Find(Object[] keyValues)
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Find(Object[] keyValues)
   at Overseer.PteroWS..ctor(String SelectedServer) in C:\Users\ramor\Documents\GitHub\Overseer\Overseer\PteroWS.cs:line 29
   at Overseer.Program..ctor() in C:\Users\ramor\Documents\GitHub\Overseer\Overseer\Program.cs:line 19
   at Overseer.Program.Main() in C:\Users\ramor\Documents\GitHub\Overseer\Overseer\Program.cs:line 14
   at Overseer.Program.&lt;Main&gt;()
/mnt/drive/Bots/Overseer/startOverseer.sh: line 8: 31192 Aborted                 /mnt/drive/Bots/Overseer/Overseer &gt;&gt; /mnt/drive/Bots/Overseer/BotLog.txt

This error seems related more to the actual program being run though, and is extremely strange since again, this works when run manually.

This is running on a Raspberry Pi 4

Attempted adding the path variable to both the script and the crontab to no effect.

答案1

得分: 1

Maybe the program is looking for an .ini or so. You can try to cd into the script dir before starting.

Example cron:

# m h  dom mon dow   command
* * * * * cd /mnt/drive/Bots/Overseer && startOverseer.sh >> /mnt/drive/Bots/Overseer/CronLog.txt 2>&1

Edit:
You can cd into scriptdir als in the script itself:

#!/bin/bash
pidof  Overseer >>/dev/null
if [[ $? -ne 0 ]] ; then
    echo "Restarting Overseer:     $(date)" >> /mnt/drive/Bots/Overseer/Log.txt
    cd /mnt/drive/Bots/Overseer && Overseer >> /mnt/drive/Bots/Overseer/BotLog.txt
else
    echo "No action necessary.     $(date)" >> /mnt/drive/Bots/Overseer/Log.txt
fi

Edit: Some fine tuning:

#!/usr/bin/env bash
printf -v date '%(%c)T\n' -1  # Actual date and time
LOG_FILE="/mnt/drive/Bots/Overseer/Log.txt"

if ! pidof Overseer &>/dev/null ; then
  echo "Restarting Overseer:     $date" >> "$LOG_FILE"
  cd /mnt/drive/Bots/Overseer && Overseer >> "$LOG_FILE"
else
  echo "No action necessary.     $date" >> "$LOG_FILE"
fi

printf eliminates the use of external date command

英文:

Maybe the program is looking for an .ini or so. You can try to cd into the script dir before starting.

Example cron:

# m h  dom mon dow   command
* * * * * cd /mnt/drive/Bots/Overseer &amp;&amp; startOverseer.sh &gt;&gt; /mnt/drive/Bots/Overseer/CronLog.txt 2&gt;&amp;1

Edit:
You can cd into scriptdir als in the script itself:

pidof  Overseer &gt;/dev/null
if [[ $? -ne 0 ]] ; then
        echo &quot;Restarting Overseer:     $(date)&quot; &gt;&gt; /mnt/drive/Bots/Overseer/Log.txt
        cd /mnt/drive/Bots/Overseer &amp;&amp; Overseer &gt;&gt; /mnt/drive/Bots/Overseer/BotLog.txt
else
    echo &quot;No action necessary.     $(date)&quot; &gt;&gt; /mnt/drive/Bots/Overseer/Log.txt
fi

Edit: Some fine tuning:

printf -v date &#39;%(%c)T\n&#39; -1  # Actual date and time
LOG_FILE=&quot;/mnt/drive/Bots/Overseer/Log.txt&quot;

if ! pidof Overseer &amp;&gt;/dev/null ; then
  echo &quot;Restarting Overseer:     $date&quot; &gt;&gt; &quot;$LOG_FILE&quot;
  cd /mnt/drive/Bots/Overseer &amp;&amp; Overseer &gt;&gt; &quot;$LOG_FILE&quot;
else
  echo &quot;No action necessary.     $date&quot; &gt;&gt; &quot;$LOG_FILE&quot;
fi

printf eliminates the use of external date command

huangapple
  • 本文由 发表于 2023年6月29日 20:21:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76581015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定