机械化rake任务适用于某些服务器而不适用于其他服务器?

时间:2012-04-10 13:57:57

标签: ruby ruby-on-rails-3 rake nokogiri mechanize

我不确定是否应该在ServerFault或者此处询问这是否是在Rails 3.2.3应用程序中特定于Mechanize和Nokogiri的服务器问题。

我有一个rake任务,可以从我们的某个服务提供商网站上删除纬度和经度。

我已将任务与其他任务一起设置在'crontab -e'中。出于某种原因,在两个假设的服务器上,一个服务器无法完成rake任务,并出现以下错误:

X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
Message-Id: <20120410134631.2CFA624B76@localhost>
Date: Tue, 10 Apr 2012 14:46:30 +0100 (BST)

rake aborted!
/var/www/railsapp/lib/tasks/peoplesafelocation.rake:29: undefined (?...) sequence: /new GLatLng\(\s*(?<lat>.+?)\s*,\s*(?<long>.+?)\s*\)/

两台服务器都运行Rails 3.2.3,Ruby 1.9.2。

我无法理解为什么它会在一台服务器上使用'undefined(?...)sequence失败但不会失败。

两台服务器都使用RVM并运行Ubuntu 10.04。

完整的佣金任务如下:

desc "Import Peoplesafe Location"
task :fetch_peoplesafelocation => :environment do

# Logs into provider.co.uk/live and retrieved latitude and longitude.
require 'rubygems'
require 'mechanize'
require 'logger'
require 'nokogiri'

# Create a new mechanize object
agent = Mechanize.new

# Load the Peoplesafe website
page = agent.get("http://provider.co.uk/live/")

# Select the first form
form = agent.page.forms.first
form.username = 'User'
form.password = 'Password'

# Submit the form
page = form.submit form.buttons.first

page = agent.get("http://provider.co.uk/live/?gps&cid=AAXA-PJZM6M")

html_doc = page.root

script = page.at('/html/head/script[not(@src)]')
parts = script.text.match(/new GLatLng\(\s*(?<lat>.+?)\s*,\s*(?<long>.+?)\s*\)/)

#puts parts[:lat], parts[:long]

Location.create(:latitude => parts[:lat], :longitude => parts[:long])
puts 'Location Updated'

任何指针都将不胜感激!

2 个答案:

答案 0 :(得分:2)

问题源于正则表达式和使用旧版ruby。

使用RVM很容易造成这种情况。

默认情况下,RVM只加载它的配置,它是一个交互式shell。 Cronjobs默认使用sh shell。

RVM附带了一个shell包装器来处理这个问题。在你的cronjob的顶部添加SHELL=/path/to/rvm/bin/rvm-shell(b / c我登录到服务器以帮助)这个路径是/usr/local/bin/rvm/bin/rvm-shell设置这将导致包含正确的rvm路径。

下一步是修复cron命令。由于我们使用rvm-shell,我们想要删除使用rvm使用正确gems(rake等)的路径。

删除rake的绝对路径,并在crontab顶部添加SHELL变量后,所有crons将开始正确触发。

答案 1 :(得分:1)

这个错误消息是由ruby 1.8.7中的正则表达式引擎引发的;例如,见this question。所以如果你实际上在两台机器上都使用ruby 1.9.3,这应该可行。

Ruby 1.8.7:

$ rvm 1.8.7-p334
$ irb
1.8.7 :002 > "foo".match(/new GLatLng\(\s*(?<lat>.+?)\s*,\s*(?<long>.+?)\s*\)/)
SyntaxError: compile error
(irb):2: undefined (?...) sequence: /new GLatLng\(\s*(?<lat>.+?)\s*,\s*(?<long>.+?)\s*\)/
from (irb):2

Ruby 1.9.2:

$ rvm 1.9.2-p290
$ irb
1.9.2p290 :001 > "foo".match(/new GLatLng\(\s*(?<lat>.+?)\s*,\s*(?<long>.+?)\s*\)/)
=> nil 

因此请仔细检查您是否确实在失败的服务器上使用了正确的rvm ruby​​。首先,检查您是否使用

将1.9.2或更高版本设置为默认值
rvm 1.9.2 --default

并且rvm可执行文件位于任何可能安装的系统ruby之前的路径中。此外,请注意cronjobs默认情况下不会使用户的环境可用 - 您需要显式传递它或从登录shell中执行cron作业(请参阅示例http://danielsz.posterous.com/how-to-run-rvm-scripts-as-cron-jobs)。