Perl 脚本在 crontab 中执行时无法写入数据库,尽管如果手动执行则可以写入
Perl script unable to write to database when executed in crontab despite being able to write if executed manually
我已经为这个问题苦苦挣扎了一段时间..我已经尝试了很多解决方案,例如:
Why can't DBD::SQLite insert into a database through my Perl CGI script?
简介
几周前,我将我的服务器从 Laravel 4.0 迁移到另一台服务器,该服务器现在是 Laravel 5.0 的最新版本。
在旧服务器中,我有一个 Perl 文件,它是我 运行 每 30 分钟使用一次名为 getListOfClasses.pl
[= 的 crontab 28=]
在我的 OLD 服务器上使用以下 crontab
命令,我会 运行 这个:
0,30 * * * * /var/www/loop/storage/scripts/getListOfClasses.pl >> /var/www/loop/storage/logs/laravel-scraper.log 2>&1
它在 /var/www/loop/storage/scripts/getListOfClassesFromSubjects.pl
中执行抓取程序并在 /var/www/loop/storage/database.sqlite
中写入我的数据库
在我搬家后,Laravel 5.0 将默认数据库位置从 storage
更改为 database
,因此我编辑了我的 crontab 以反映该更改以及数据库名称:
my $dbFile = '../storage/database.sqlite';
到新的文件路径位置
my $dbFile = '../../database/database.sqlite';
问题
如果我 运行 我的刮板手动位于:
/var/www/schedulizer/storage/scripts/getListOfClasses.pl
我可以很好地抓取。但是,如果我依赖 crontab 来执行脚本,我会收到以下错误:
DBI connect('dbname=../../database/database.sqlite','',...) failed: unable to open database file at /var/www/schedulizer/storage/scripts/getListOfClasses.pl line 22.
第 22 行是 my $dbh = DBI->connect($dsn, $user, $password, {
。我认为这行代码不相关 - 我猜我的服务器在写入该数据库时出现问题。
我的 SQLite 数据库的权限如下:
-rwxrwxrwx 1 www-data root 8845312 Nov 3 00:05 database.sqlite
数据库所在的文件夹具有以下权限:
drwxr-xr-x 5 www-data root 4096 Nov 3 00:05 database
这些权限级别都与我的旧服务器对数据库文件和文件夹的权限级别相同。我还在数据库文件上尝试了 chown
和 chmod 777
所以它拥有所有可能的权限。仍然没有运气。
有人知道为什么吗?
手动测试时,您可能会转到脚本的正确工作目录进行编辑。从任何其他位置启动它也很可能会导致失败。
- 使用绝对路径而不是相对路径以确保您访问正确的现有目录。
- 在 crontab 中的命令前包含一个
cd /some/where ;
。 Cron 设置您的主目录,无论调用的程序位于何处。
第二个建议是更便携的,因为它不需要在位置或机器更改时更改脚本;您只需在您的(特定于机器的)crontab 中对其进行调整即可。
我已经为这个问题苦苦挣扎了一段时间..我已经尝试了很多解决方案,例如:
Why can't DBD::SQLite insert into a database through my Perl CGI script?
简介
几周前,我将我的服务器从 Laravel 4.0 迁移到另一台服务器,该服务器现在是 Laravel 5.0 的最新版本。
在旧服务器中,我有一个 Perl 文件,它是我 运行 每 30 分钟使用一次名为 getListOfClasses.pl
[= 的 crontab 28=]
在我的 OLD 服务器上使用以下 crontab
命令,我会 运行 这个:
0,30 * * * * /var/www/loop/storage/scripts/getListOfClasses.pl >> /var/www/loop/storage/logs/laravel-scraper.log 2>&1
它在 /var/www/loop/storage/scripts/getListOfClassesFromSubjects.pl
中执行抓取程序并在 /var/www/loop/storage/database.sqlite
在我搬家后,Laravel 5.0 将默认数据库位置从 storage
更改为 database
,因此我编辑了我的 crontab 以反映该更改以及数据库名称:
my $dbFile = '../storage/database.sqlite';
到新的文件路径位置
my $dbFile = '../../database/database.sqlite';
问题
如果我 运行 我的刮板手动位于:
/var/www/schedulizer/storage/scripts/getListOfClasses.pl
我可以很好地抓取。但是,如果我依赖 crontab 来执行脚本,我会收到以下错误:
DBI connect('dbname=../../database/database.sqlite','',...) failed: unable to open database file at /var/www/schedulizer/storage/scripts/getListOfClasses.pl line 22.
第 22 行是 my $dbh = DBI->connect($dsn, $user, $password, {
。我认为这行代码不相关 - 我猜我的服务器在写入该数据库时出现问题。
我的 SQLite 数据库的权限如下:
-rwxrwxrwx 1 www-data root 8845312 Nov 3 00:05 database.sqlite
数据库所在的文件夹具有以下权限:
drwxr-xr-x 5 www-data root 4096 Nov 3 00:05 database
这些权限级别都与我的旧服务器对数据库文件和文件夹的权限级别相同。我还在数据库文件上尝试了 chown
和 chmod 777
所以它拥有所有可能的权限。仍然没有运气。
有人知道为什么吗?
手动测试时,您可能会转到脚本的正确工作目录进行编辑。从任何其他位置启动它也很可能会导致失败。
- 使用绝对路径而不是相对路径以确保您访问正确的现有目录。
- 在 crontab 中的命令前包含一个
cd /some/where ;
。 Cron 设置您的主目录,无论调用的程序位于何处。
第二个建议是更便携的,因为它不需要在位置或机器更改时更改脚本;您只需在您的(特定于机器的)crontab 中对其进行调整即可。