Shebang
We briefly mentioned shebang before but never went into what it actually is. Let's create a file hello.rb with a very simple Ruby program.
This Ruby file will print "Hello, world" on the screen if executed. Let's run it using ruby.
Here we have actually executed ruby and passed "hello.rb" as the argument. The ruby program read the file hello.rb and executed it. However, we normally run various files without having to pass them as arguments to other programs.
For example, you may be already familiar with irb (pronounced eye-are-bee), the Ruby's interactive shell. To invoke it, we can just type irb in the console
irb
How can we run our little program just like irb by typing its name in the terminal without explicitly invoking ruby? We'll need to do two things: fix the permissions and add a shebang. Let's try running the file first.
Make sure you quit irb if you launched it.
$ ./hello.rb-bash: ./hello.rb: Permission denied
(Don't worry about ./ right now. It's simply a hint for the terminal that we want to run hello.rb from the current directory. Remember that "." stands for current directory?)
The reason we get permission denied error is that the file doesn't have the "executable" permission by default (list the directory in long format to verify). Let's give the USER (u) permission to EXECUTE (x) the file.
chmod u+x hello.rb
Try running the file right now. The permission denied error is now gone but we get another problem.
$ ./hello.rb./hello.rb: line 1: puts: command not found
So the terminal (or the shell, to be more precise) complains that it doesn't know what "puts" on line 1 means: command not found. Why is that?
Try to see the situation from the computer's point of view. We asked it to run a program in the file hello.rb but we didn't tell the computer what programming language it was. Was it Ruby? Python? PHP? Something else? The file does have an "rb" extention hinting that it might be Ruby but the computer wouldn't make this assumption. And, even if it's Ruby, we probably have several versions of Ruby installed on the machine: 1.8.6, 1.9.3, 2.0.0, etc. Which one should be used to run our file? The computer needs a specific instruction.
Without a specific instruction it will assume that the file is a "shell script", that is, a set of instructions in the same language that the command line uses. That's why you'll get exactly the same error if try to typeputs 'Hello, world'
in the terminal.
Shebang is the instruction for your computer that tells what program to use to execute your script. It is a combination of a hash and an exclamation mark followed by the path to the interpreter, placed on the very first line of the file.
We want our file to be executed by Ruby, so let's find out where ruby interpreter is first.
$ which ruby/Users/shadchnev/.rvm/rubies/ruby-2.0.0-p0/bin/ruby
On my machine, the current version of ruby is located at "/Users/shadchnev/.rvm/rubies/ruby-2.0.0-p0/bin/ruby". Find out where your ruby is and add a shebang to your hello.rb usingAtom.
This tells the command line to use this ruby interpreter to execute the file. Now you can type "./hello.rb" and it will print "Hello, world".
./hello.rbHello, world!
What's happening behind the scenes is that the shell (command-line) passes the contents of the file to the interpreter that we specified in the shebang.
However, we've just hardcoded the path to Ruby right in the file. It will work on this computer but not on any other because the path to Ruby will be different. There is a better solution to this problem. Change your shebang to look like this.
The "/usr/bin/env ruby" command loads the "environment" (we'll discuss it in a minute) and executes whatever ruby you have on your machine. It may be 1.9.3 on mine and 2.0.0 on yours. This is a much more portable solution than the one we used before.
Remember we mentioned irb as an example of a program that we can run without typing "ruby"? It also has shebang on the first line.
Note that the "which irb" command that returns us the path to irb (try it!) is enclosed in backticks (different from apostrophes; located on the left of the "Z" key). This makes the command line "expand" the command, so the real command executed by the computer is
head /Users/shadchnev/.rvm/rubies/ruby-2.0.0-p247/bin/irb
The head command that was mentioned above, shows the first few lines of a file. In the screenshot above you can see the shebang on the first line and some Ruby code starting from line two.
source: Makers Academy