我正在尝试设置一个从Rails应用程序启动的简单计时器。此计时器应等待其持续时间,然后启动一个将启动./script/runner的shell脚本并完成初始请求。我需要脚本/跑步者,因为我需要访问ActiveRecord。
这是我在Rails中的测试行
output = `at #{(Time.now + 60).strftime("%H:%M")} < #{Rails.root}/lib/parking_timer.sh STRING_VARIABLE`
return render :text => output
然后我的parking_timer.sh看起来像这样
#!/bin/sh
~/PATH_TO_APP/script/runner -e development ~/PATH_TO_APP/lib/ParkingTimer.rb $1
echo "All Done"
最后,ParkingTimer.rb使用
读取传递的变量ARGV.each do|a|
puts "Argument: #{a}"
end
问题是Unix命令“at”似乎不喜欢变量而只想处理文件名。我要么得到两个错误中的一个,取决于我如何定位“
如果我像这样在右手边加上引号
...“〜/ PATH_TO_APP / lib / parking_timer.sh STRING_VARIABLE”
我明白了,
-bash:〜/ PATH_TO_APP / lib / parking_timer.sh STRING_VARIABLE:没有这样的文件或目录
我把引号留下来,我明白了,
at:乱码时间
这一切都发生在运行Rails 2.3和Mac的Mac OS 10.6盒子上。 Ruby 1.8.6
我已经和BackgrounDrb搞混了,并决定了它的全部PITA。我需要能够在到期前的任何时候取消这份工作。
答案 0 :(得分:1)
在玩了irb
之后,这就是我找到的。
在ruby完成任何必要的解释之后,反引号运算符会调用shell。对于我的测试用例,strace
输出看起来像这样:
execve("/bin/sh", ["sh", "-c", "echo at 12:57 < /etc/fstab"], [/* 67 vars */]) = 0
既然我们知道它在做什么,那么让我们来看看你的命令将如何执行:
/bin/sh -c "at 12:57 < RAILS_ROOT/lib/parking_timer.sh STRING_VARIABLE"
看起来非常奇怪。您真的想将parking_timer.sh
(脚本)作为输入加入at
命令吗?
你最终想要的是这样的事情:
/bin/sh -c "RAILS_ROOT/lib/parking_timer.sh STRING_VARIABLE | at 12:57"
因此,parking_timer.sh
命令的输出将成为at
命令的输入。
所以,请尝试以下方法:
output = `#{Rails.root}/lib/parking_timer.sh STRING_VARIABLE | at #{(Time.now + 60).strftime("%H:%M")}`
return render :text => output
您始终可以使用strace
或truss
来查看正在发生的事情。例如:
strace -o strace.out -f -ff -p $IRB_PID
然后grep '^exec' strace.out*
查看命令的执行位置。