Rest POST 在 CRON 任务中不工作(它与手动 rake 命令一起工作)
Rest POST not working in CRON task(it works with manual rake command)
所以,我有一个应用程序可以与 Whenever Gem 配合使用来执行计划任务。然后,我有一个任务使用 RestClient 执行 post 请求,当我自己在终端上使用“rake”执行它时它工作正常。但是当任务通过 cron 作业执行时,它不起作用。 post 请求如下所示:
urlOAuth = ENV['URL_AUTH']
client_id = ENV['CLIENT_ID']
client_secret = ENV['CLIENT_SECRET']
data = {
grant_type: 'client_credentials',
scope: 'read-data',
client_id: client_id,
client_secret: client_secret
}
result = RestClient.post(urlOAuth, data)
正如我所说,当使用手动 rake 命令执行此任务时,它工作正常。当任务被cronjob执行时,returns这个错误:
rake aborted!
ArgumentError: must pass :url
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:79:in `initialize'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:63:in `new'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:63:in `execute'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient.rb:70:in `post'
/root/micro-app-api-idfm/lib/tasks/get_send_json.rake:22:in `block in <main>'
/usr/local/rvm/gems/ruby-2.6.5/gems/rake-13.0.1/exe/rake:27:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.6.5/bin/ruby_executable_hooks:24:in `eval'
/usr/local/rvm/gems/ruby-2.6.5/bin/ruby_executable_hooks:24:in `<main>'
所以,我尝试在任务代码中直接传递url,仍然报错:
rake aborted!
RestClient::BadRequest: 400 Bad Request
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/abstract_response.rb:249:in `exception_with_response'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/abstract_response.rb:129:in `return!'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:836:in `process_result'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:743:in `block in transmit'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:727:in `transmit'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:163:in `execute'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:63:in `execute'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient.rb:70:in `post'
/root/micro-app-api-idfm/lib/tasks/get_send_json.rake:22:in `block in <main>'
/usr/local/rvm/gems/ruby-2.6.5/gems/rake-13.0.1/exe/rake:27:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.6.5/bin/ruby_executable_hooks:24:in `eval'
/usr/local/rvm/gems/ruby-2.6.5/bin/ruby_executable_hooks:24:in `<main>'
我该怎么办?不知道为什么这不起作用,因为它可以与手动 rake 命令一起正常工作。如果有任何帮助,我将不胜感激,提前致谢。
编辑¹.:
我尝试引发异常以具体检查此 400 错误请求发生了什么。这是我得到的:
{
"error" : "invalid_client",
"error_description" : "Client authentication failed (e.g. unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. "
}
rake aborted!
这仍然没有意义,因为它在手动执行任务时起作用,所以客户端应该有效
您使用的是绝对文件路径吗?我对 rake 一无所知,但由于在 cron 任务和它运行的脚本中使用相对文件路径,我把我安排的每个 cronjob 搞砸了。似乎它找到了 rake 可执行文件,但没有找到您要执行的脚本。
例如使用绝对文件路径在每天凌晨 12 点为 python 脚本安排 cron 作业:
* 0 * * * /usr/bin/python3 /home/user/file
此外,确保脚本中的文件路径也是绝对的(cron 不是 运行 来自该目录的脚本)。
用户 运行 rake 任务没有在 ENV
中设置环境变量。这就是为什么当您直接传入 URL 时会收到不同的错误 (400 Bad Request)。
在第一种情况下根本没有 ENV
变量。在第二种情况下,您传入了 URL (因此可以发出请求并收到响应)但是您遗漏了所有其他变量,这导致服务器说您提出了错误的请求.
解决方案是 为用户 运行 ruby
传递 ENV
变量或 硬编码您的值在你的脚本中.
感谢@anothermh,我设法发现 cron 出于某种原因没有访问 ENV 变量,但仍然没有找到原因。
但是,因为我使用的是 dotenv
gem,所以锻炼是使用它自己的任务语法(我以前不必这样做,但现在我这样做了,不知道为什么)。这是在每个任务开始时做这样的事情,以确保 .env 文件被“手动”加载:
require 'dotenv/tasks'
task mytask: :dotenv do
# things that require .env
end
您可以在自己的 dotenv github 页面中查看更多内容。感谢那些试图提供帮助的人!
https://github.com/bkeepers/dotenv
所以,我有一个应用程序可以与 Whenever Gem 配合使用来执行计划任务。然后,我有一个任务使用 RestClient 执行 post 请求,当我自己在终端上使用“rake”执行它时它工作正常。但是当任务通过 cron 作业执行时,它不起作用。 post 请求如下所示:
urlOAuth = ENV['URL_AUTH']
client_id = ENV['CLIENT_ID']
client_secret = ENV['CLIENT_SECRET']
data = {
grant_type: 'client_credentials',
scope: 'read-data',
client_id: client_id,
client_secret: client_secret
}
result = RestClient.post(urlOAuth, data)
正如我所说,当使用手动 rake 命令执行此任务时,它工作正常。当任务被cronjob执行时,returns这个错误:
rake aborted!
ArgumentError: must pass :url
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:79:in `initialize'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:63:in `new'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:63:in `execute'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient.rb:70:in `post'
/root/micro-app-api-idfm/lib/tasks/get_send_json.rake:22:in `block in <main>'
/usr/local/rvm/gems/ruby-2.6.5/gems/rake-13.0.1/exe/rake:27:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.6.5/bin/ruby_executable_hooks:24:in `eval'
/usr/local/rvm/gems/ruby-2.6.5/bin/ruby_executable_hooks:24:in `<main>'
所以,我尝试在任务代码中直接传递url,仍然报错:
rake aborted!
RestClient::BadRequest: 400 Bad Request
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/abstract_response.rb:249:in `exception_with_response'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/abstract_response.rb:129:in `return!'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:836:in `process_result'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:743:in `block in transmit'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:727:in `transmit'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:163:in `execute'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient/request.rb:63:in `execute'
/usr/local/rvm/gems/ruby-2.6.5/gems/rest-client-2.1.0/lib/restclient.rb:70:in `post'
/root/micro-app-api-idfm/lib/tasks/get_send_json.rake:22:in `block in <main>'
/usr/local/rvm/gems/ruby-2.6.5/gems/rake-13.0.1/exe/rake:27:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.6.5/bin/ruby_executable_hooks:24:in `eval'
/usr/local/rvm/gems/ruby-2.6.5/bin/ruby_executable_hooks:24:in `<main>'
我该怎么办?不知道为什么这不起作用,因为它可以与手动 rake 命令一起正常工作。如果有任何帮助,我将不胜感激,提前致谢。
编辑¹.:
我尝试引发异常以具体检查此 400 错误请求发生了什么。这是我得到的:
{
"error" : "invalid_client",
"error_description" : "Client authentication failed (e.g. unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. "
}
rake aborted!
这仍然没有意义,因为它在手动执行任务时起作用,所以客户端应该有效
您使用的是绝对文件路径吗?我对 rake 一无所知,但由于在 cron 任务和它运行的脚本中使用相对文件路径,我把我安排的每个 cronjob 搞砸了。似乎它找到了 rake 可执行文件,但没有找到您要执行的脚本。
例如使用绝对文件路径在每天凌晨 12 点为 python 脚本安排 cron 作业:
* 0 * * * /usr/bin/python3 /home/user/file
此外,确保脚本中的文件路径也是绝对的(cron 不是 运行 来自该目录的脚本)。
用户 运行 rake 任务没有在 ENV
中设置环境变量。这就是为什么当您直接传入 URL 时会收到不同的错误 (400 Bad Request)。
在第一种情况下根本没有 ENV
变量。在第二种情况下,您传入了 URL (因此可以发出请求并收到响应)但是您遗漏了所有其他变量,这导致服务器说您提出了错误的请求.
解决方案是 为用户 运行 ruby
传递 ENV
变量或 硬编码您的值在你的脚本中.
感谢@anothermh,我设法发现 cron 出于某种原因没有访问 ENV 变量,但仍然没有找到原因。
但是,因为我使用的是 dotenv
gem,所以锻炼是使用它自己的任务语法(我以前不必这样做,但现在我这样做了,不知道为什么)。这是在每个任务开始时做这样的事情,以确保 .env 文件被“手动”加载:
require 'dotenv/tasks'
task mytask: :dotenv do
# things that require .env
end
您可以在自己的 dotenv github 页面中查看更多内容。感谢那些试图提供帮助的人! https://github.com/bkeepers/dotenv