Ruby on Rails script console - ruby-on-rails

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.

Related

activating conda env vs calling python interpreter from conda env

What exactly is the difference between these two operations?
source activate python3_env && python my_script.py
and
~/anaconda3/envs/python3_env/bin/python my_script.py ?
It appears that activating the environment adds some variables to $PATH, but the second method seems to access all the modules installed in python3_env. Is there anything else going on under the hood?
You are correct, activating the environment adds some directories to the PATH environment variable. In particular, this will allow any binaries or scripts installed in the environment to be run first, instead of the ones in the base environment. For instance, if you have installed IPython into your environment, activating the environment allows you to write
ipython
to start IPython in the environment, rather than
/path/to/env/bin/ipython
In addition, environments may have scripts that add or edit other environment variables that are executed when the environment is activated (see the conda docs). These scripts can make arbitrary changes to the shell environment, including even changing the PYTHONPATH to change where packages are loaded from.
Finally, I wrote a very detailed answer of what exactly is happening in the code over there: Conda: what happens when you activate an environment? That may or may not still be up-to-date though. The relevant part of the answer is:
...the build_activate method adds the prefix to the PATH via the _add_prefix_to_path method. Finally, the build_activate method returns a dictionary of commands that need to be run to "activate" the environment.
And another step deeper... The dictionary returned from the build_activate method gets processed into shell commands by the _yield_commands method, which are passed into the _finalize method. The activate method returns the value from running the _finalize method which returns the name of a temp file. The temp file has the commands required to set all of the appropriate environment variables.
Now, stepping back out, in the activate.main function, the return value of the execute method (i.e., the name of the temp file) is printed to stdout. This temp file name gets stored in the Bash variable ask_conda back in the _conda_activate Bash function, and finally, the temp file is executed by the eval Bash function.
So you can see, depending on the environment, running conda activate python3_env && python my_script.py and ~/anaconda3/envs/python3_env/bin/python my_script.py may give very different results.

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.

Edit bash PATH variable for Rails application

I have application minizinc in file ~/.bashrc, and I can call it on bash. I am building a Rails application that calls minizinc from bash, but I cannot do it. After executing this:
#cmd = ` bash -c "minizinc #{path} -n 1" `
I get the following error:
bash: minizinc: command not found
How can I change the Rails application user's PATH variable from the application? Or how do I tell the Rails application where this bash application is located?
You have several options here. The one I think best suits your case and would recommend is using the command directly, instead of calling Bash to do the same as Ruby:
#cmd = `minizinc #{path} -n 1`
If you use it like this, the command is executed in a shell with an environment similar to the one where Ruby is running. Which means that the PATH variable will be the same. So if the dir containing the executable minizinc is in PATH when you start the Rails server, it should also be in the PATH variable of the shell running that command.
Now, if you really need to use Bash in the middle, I strike it as odd that the PATH variable is not the same as in Ruby (I tried it using IRB and seems to work as expected). You can check it by replacing your command with
bash -c "echo $PATH"
It should print the same value as
puts ENV['PATH']
when run in the Rails console.
If, after checking it, you see that the PATH variable of your Rails environment is incorrect, you can set it specifically for the Rails server:
PATH="<path_to_minizinc_dir>:$PATH" rails server
This sets the value of the PATH environment variable only for the command you are about to execute, in this case rails server.
Alternatively, you can surpass all this by simply using the absolute path to the executable:
#cmd = `bash -c "/full/path/to/minizinc #{path} -n 1"`
If you provide the full path to the command you want to execute, the PATH environment variable simply won't come into play, but I imagine this would be suboptimal for your case.

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

have a relative shebang line

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)

Resources