unix at命令将变量传递给shell脚本?

时间:2010-03-31 16:42:16

标签: ruby-on-rails ruby unix shell macos

我正在尝试设置一个从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。我需要能够在到期前的任何时候取消这份工作。

1 个答案:

答案 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

您始终可以使用stracetruss来查看正在发生的事情。例如:

strace -o strace.out -f -ff -p $IRB_PID

然后grep '^exec' strace.out*查看命令的执行位置。