When we write scripts, we often want to run them from the shell. There is a pattern common to most scripting languages for making a script executable:
- Shebang: start the script by instructing the shell what executable to use to run the script:
- Verify that the script is being called directly
- Make the script executable with
Here is how that pattern can be applied to Ruby scripts.
To tell the shell what program to run when the shell invokes the Ruby script, start the script with a “shebang”* line:
/usr/bin/env loads the first
ruby that is found in our
PATH. This allows us to avoid hard-coding the full path to
ruby– handy when multiple rubies are installed or are installed in different locations on different systems, e.g.
* Pronounced shuh-bang, sorry, Ricky Martin fans.
Verify that script is being executed
To avoid running the script when it is included from elsewhere as a file, verify that the script is the file that is being run:
if $PROGRAM_NAME==__FILE__ puts :hello_world! end
This is especially important when running the script results in changes or results in destructive actions, such as performing updates, moving files or deleting data or files.
I often start writing functionality by developing it in isolation in a dedicated script, and subsequently move that script’s functionality into the application’s library. Verifying that the script is being executed is a failsafe in case I forget to remove the executing code from the script, so that the functionality isn’t accidentally run when the new library is required or included from elsewhere in the application.
Make script executable
To make the script executable, in the shell run
chmod +x on the script. Eg. for a file named named
chmod +x hello-world
The script can then be invoked from the local directory by running:
Namespace All The Things
Using namespaces, eg. modules and classes, can help with organization. For example, a
HelloWorld module with a
run() method can be used to organize the hello-world functionality:
module HelloWorld def self.run puts :hello_world! end end
Which would be called by running:
Putting it all together
Add the following code to the file
#!/usr/bin/env ruby module HelloWorld def self.run puts :hello_world! end end if $PROGRAM_NAME==__FILE__ HelloWorld::run() end
Make the script executable by running:
chmod +x hello-world
Run the script:
Which generates the output:
- Shebang: https://en.wikipedia.org/wiki/Shebang_(Unix)
- Ruby pre-defined globals: https://ruby-doc.org/core-3.0.1/doc/globals_rdoc.html