have a relative shebang line - ruby-on-rails

I'm writing a rails app and need to run come scripts through ./script/runner
while i could put
#!/home/cannon/src/timetracker/script/runner
at the top, that wont work in production where it needs to be more like
#!/var/www/loclahost/htdocs/timetracker/script/runner -e=production
since ./script is not in my path, and I don't want it to be, how can I allow this to be set up,
I am using a cron job to run it on a Linux box

Use env in the shebang line to look things up in the path:
#!/usr/bin/env ./script/runner

Use this at the top of your (ruby) script to re-exec it under the local ./script/runner (which should then define Rails so you avoid an infinite loop)
exec("./script/runner",$0,*ARGV) unless defined?(Rails)
(So use a regular 'ruby' shebang at the top, whether it's #!/usr/bin/ruby or #!/usr/bin/env ruby or whatever the flavor)

Related

New to Command Prompt - Do I need to prefix every command with "Jruby -S ..."

I'm new to using Window's Command Prompt, and also to developing with Ruby on Rails. Possibly a silly question but one that I'm sure everyone who learns with CodeCademy will end up asking; right now I'm prefixing every command for my project with 'Jruby -S ...", for example:
C:\users\MyName\MyProject> Jruby -S rails new MyApp
...
C:\users\MyName\MyProject> Jruby -S bundle install
...
C:\users\MyName\MyProject> Jruby -S rake db:migrate
Can I use some kind of alternative shell to save me typing Jruby -S every time? I'm aware of bash and powershell but have basically zero knowledge of whether I should be using them...
Thanks folks!
EDIT
Lots of helpful suggestions below, but I was really looking for a shell to mimic the functionality of the console on codecademy.com (which I believe is supposed to work like a Mac's 'bash' program?). Thanks anyway.
I'm new to using Window's Command Prompt
The CMD works very similarly to the GUI/Shell -- you have to call applications and then run commands with them.
The difference between CMD and windows is that CMD is "naked" - you have to ensure all the paths are correct, and that you're calling the correct application each time.
For example, calling rails server literally translates as:
Program = ruby.exe / rails
Command = server
CMD uses the PATH environment variable to make this process smoother.
The PATH var basically allows you to reference applications on your computer from the CLI (command line interface). This means that if you have an application (EG ruby.exe), you can add the ruby.exe directory to your PATH variable, allowing you to call ruby ... straight from cmd.
--
In your case, I don't have much experience with JRuby; I do know, however, that if you want to invoke the functionality of that application, you have to call it from the cli.
Hopefully my answer gives some context.
You can do that with powershell.
I'm sure that there should be a better way to do that, but you can try this
$ruby = "Jruby"
$s = "-S"
& $ruby $s rails new MyApp
I don't work on windows, however the jruby zip files on the download site have a bin directory with .bat and .exe files for jruby, rake, and gem. You could just add the directory you installed jruby to and the 'bin' subdirectory to your PATH to start.
set JRUBY_HOME= your_installed_jruby
set PATH= %PATH%;%JRUBY_HOME%\bin
http://jruby.org/download
I don't know what the windows installer does, but I would think it would do something similar.

How do I run 'rails server' inside a shell script?

I'm trying to write a shell script that automatically runs my rails app in a virtual machine.
My script code is this:
#!/bin/sh
PATH='/usr/local/rvm/gems/ruby-2.0.0-p481/bin'
cd /home/lgdelacruz/SampleApp
rails server
But for some reason it doesn't see all the dependencies. this gives me the error
/usr/bin/env: ruby: No such file or directory
I'm positive ruby is installed in the virtual machine. I can run rails server by manually going inside my virtual machine going to my SampleApp folder and running rails server there and everything works fine. But for some reason when I put all that in a shell script. it doesn't work.
You've probably got to initialize RVM in your script first. Try putting this line in:
source "$HOME/.rvm/scripts/rvm"
You might also need to specify a gemset, if you're using something other than the default:
rvm use #mygemset
See the RVM scripting docs for details.
In your shell script, you've reset your path to only include /usr/local/rvm/gems/ruby-2.0.0-p481/bin. ruby is usually installed somewhere like /usr/local/bin
instead you could concatenate that directory onto the end of your existing path.
something like:
export PATH=$PATH:/usr/local/rvm/gems/ruby-2.0.0.p482/bin

How to pass env variables to GNOME

I want to replace some utilities(like telnet) with transparent wrappers(with loggers).
At first I used aliases, that worked nicely at the command line but gnome doesn't understand shell aliases so that when people would launch the utilities as the shell for a gnome-terminal profile it would run the actual utility instead of the wrapper.
Then I tried adding new folder with symlinks and prepended it to PATH(security isn't a huge concern plus its a special folder just for these symlinks) in ~/.bashrc but they still run the original(I'm guessing gnome doesn't run .bashrc since it works from the command line). Any ideas where setting path needs to go?
Maybe update-alternatives fits your needs?
I found two ways to do this that seem to work like I want(sourcing scripts for gnome env).
First putting it in ${HOME}/.gnomerc (but I found some places that say you should manually exec gnome session afterwards and others that don't(It seems to work fine without it) and I'm afraid of breaking login.)
Putting it in ~/.profile seems to work so I just
echo 'PATH=~/.symlink_dir/:${PATH}' > ~/.profile
(note that this is ignored by bash if a ~/.bash_profile exists so you may want to manually source it from ~/.bash_profile just in case
echo 'source ~/.profile' >> ~/.bash_profile).
If you really want to use your replacement utilities throughout, you could put symlinks to your replacements in /usr/bin/ (or wherever as appropriate) and move the originals to /usr/bin/originals/ (or wherever).
If you do that, you'd better make sure that your wrappers are rock solid though. Depending on what you're replacing, errors might prevent booting, which is generally undesirable.
It might not be what you are asking, but have you tried changing the commands of the launchers from the menu editor.
If you are using Gnome 3 you will have to download the alacarte package.

Ruby on Rails script console

I wasn't able to run ./script/console previously, and it used to throw an error since my script console file had included #!/usr/bin/env ruby19. After doing hit and trial I fixed this error by replacing #!/usr/bin/env ruby19 with #!/usr/bin/env ruby.
What does the above line do?
Versions:
Ruby: 1.9.2-p180
Ruby on Rails: 2.3.5
The #! (hash bang) in the first line of a text file tells the program loader in most *nix systems to invoke the program that is specified next (in this case, /usr/bin/env) with any params supplied (in this case, ruby).
/usr/bin/env is just a portable way of looking in your environment for program named in the first argument. Here it is the Ruby interpreter. If the Ruby interpreter is in your PATH, env will find it and run it using the rest of the file as input.
You probably didn't have a program named ruby19 in your PATH, so you'd get the error. You do have a program named ruby, so that works.
The shebang line in a Unix script is supposed to specify a full path, so this:
#!/usr/local/bin/ruby
is valid but this is not:
#!ruby
The problem with the first form is that, well, you need to use a full path but the actual path won't be the same on all systems. The env utility is often used to allow a script to search the PATH environment variable for the appropriate interpreter, env should always be in /usr/bin/env so you can safely use that as a full path and then let env search the PATH for the named interpreter.
From the fine manual:
env [-i] [name=value]... [utility [argument...]]
The env utility shall obtain the current environment, modify it according to its arguments, then invoke the utility named by the utility operand with the modified environment.
That isn't terribly helpful in your case but I figured I should include it anyway. The shebang use of env is a bit of a hack that doesn't use the intended behavior of env.

Optimizing Rails loading for maintenance scripts

I wrote a script that does maintenance tasks for a rails application. The script uses a class that uses models defined in the application. Just an example, let's say application defines model User, and my class (used within the script), sends messages to it, like User.find id.
I am looking for ways to optimize this script, because right now it has to load the application environment: require '../config/environment'. This takes ~15 seconds.
Had the script not use application codebase to do its job, I could have replaced model abstractions with raw SQL. But unfortunatly I can't do that because I would have to repeat the code in the script that is already present in the codebase. Not only would this violate DRY principle and require alot of work, the script would not be very maintainable, in case the model methods that I am using change.
I would like to hear ideas how to approach this problem. The script is not run from the application itself, but from the shell (with Capistrano for instance).
I hope I've described the problem clear enough. Thank you.
Could you write a little daemon that is in a read on a pipe (or named fifo, or unix domain socket, or, with more complexity, a tcp port) that accepts 'commands' that would be run on your database?
#!/usr/bin/ruby
require '../config/environment'
while (true) do
File.open("/tmp/fifo", "r") do |f|
f.each_line do |line|
case line
when "cleanup" then puts "clean!"
when "publish" then puts "published!"
else puts "invalid command, ignoring"
end
end
end
end
You could start this thing up with vixie cron's #reboot specifier, or you could run it via capistrano commands, or run it out of init or init scripts. Then you write your capistrano rules (that you have now) to simply echo commands into the fifo:
First,
mkfifo /tmp/fifo
In one terminal:
$ ./env.rb
In another terminal:
$ echo -n "cleanup" > /tmp/fifo
$ echo -n "publish" > /tmp/fifo
$ echo -n "go away" > /tmp/fifo
The output in the first terminal looks like this:
clean!
published!
invalid command, ignoring
You could make the matching as friendly (perhaps allow plain echo, rather than require echo -n as my example does) or unfriendly as you want. And the commands that get run can of course call into your model files to do their work.
Please make sure you choose a good location for your fifo -- /tmp/ is probably a bad place, as many distributions clear it on reboot. Also make sure you set the fifo owner and permission (chown and chmod) appropriately for your application -- you might not want to allow your Firefox's flash plugin to write to this file and command your database.

Resources