简体   繁体   English

UNIX在命令传递变量到shell脚本?

[英]unix at command pass variable to shell script?

I'm trying to setup a simple timer that gets started from a Rails Application. 我正在尝试设置一个从Rails应用程序启动的简单计时器。 This timer should wait out its duration and then start a shell script that will start up ./script/runner and complete the initial request. 此计时器应等待其持续时间,然后启动将启动./script/runner的Shell脚本并完成初始请求。 I need script/runner because I need access to ActiveRecord. 我需要脚本/运行程序,因为我需要访问ActiveRecord。

Here's my test lines in Rails 这是我在Rails中的测试线

output = `at #{(Time.now + 60).strftime("%H:%M")} < #{Rails.root}/lib/parking_timer.sh STRING_VARIABLE`
return render :text => output

Then my parking_timer.sh looks like this 然后我的parking_timer.sh看起来像这样

#!/bin/sh               
~/PATH_TO_APP/script/runner -e development ~/PATH_TO_APP/lib/ParkingTimer.rb $1
echo "All Done"    

Finally, ParkingTimer.rb reads the passed variable with 最后,ParkingTimer.rb使用以下命令读取传递的变量

ARGV.each do|a|
   puts "Argument: #{a}"
end

The problem is that the Unix command "at" doesn't seem to like variables and only wants to deal with filenames. 问题是Unix命令“ at”似乎不喜欢变量,而只想处理文件名。 I either get one of two errors depending on how I position "s 根据我的定位方式,我会收到两个错误之一

If I put quotes around the right hand side like so 如果我像这样在右手边加引号

... "~/PATH_TO_APP/lib/parking_timer.sh STRING_VARIABLE" ...“〜/ PATH_TO_APP / lib / parking_timer.sh STRING_VARIABLE”

I get, 我明白了

-bash: ~/PATH_TO_APP/lib/parking_timer.sh STRING_VARIABLE: No such file or directory -bash:〜/ PATH_TO_APP / lib / parking_timer.sh STRING_VARIABLE:没有这样的文件或目录

II leave the quotes out, I get, 我把报价单省略掉,我明白了,

at: garbled time 于:乱码

This is all happening on a Mac OS 10.6 box running Rails 2.3 & Ruby 1.8.6 这都是在运行Rails 2.3&Ruby 1.8.6的Mac OS 10.6盒子上发生的

I've already messed around w/ BackgrounDrb, and decided its a total PITA. 我已经把W / BackgrounDrb弄乱了,决定了它的总PITA。 I need to be able to cancel the job at any time before it is due. 我需要能够在到期之前随时取消该作业。

After playing around with irb a bit, here's what I found. 玩了一点irb之后,这就是我发现的东西。

The backtick operator invokes the shell after ruby has done any interpretation necessary. 在ruby完成必要的解释后,反引号运算符将调用shell。 For my test case, the strace output looked something like this: 对于我的测试用例, strace输出看起来像这样:

execve("/bin/sh", ["sh", "-c", "echo at 12:57 < /etc/fstab"], [/* 67 vars */]) = 0   

Since we know what it's doing, let's take a look at how your command will be executed: 因为我们知道它在做什么,所以让我们看一下如何执行命令:

/bin/sh -c "at 12:57 < RAILS_ROOT/lib/parking_timer.sh STRING_VARIABLE"

That looks very odd . 看起来很奇怪 Do you really want to pipe parking_timer.sh , the script, as input into the at command? 您是否真的想将脚本parking_timer.sh作为at命令的输入?

What you probably ultimately want is something like this: 您可能最终想要的是这样的东西:

/bin/sh -c "RAILS_ROOT/lib/parking_timer.sh STRING_VARIABLE | at 12:57"

Thus, the output of the parking_timer.sh command will become the input to the at command. 因此, parking_timer.sh命令的输出将成为at命令的输入。

So, try the following: 因此,请尝试以下操作:

 output = `#{Rails.root}/lib/parking_timer.sh STRING_VARIABLE | at #{(Time.now + 60).strftime("%H:%M")}`
return render :text => output

You can always use strace or truss to see what's happening. 您始终可以使用stracetruss来查看发生了什么。 For example: 例如:

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

Then grep '^exec' strace.out* to see where the command is being executed. 然后使用grep '^exec' strace.out*来查看命令的执行位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM