00:00:04.560
Okay, everybody. I’m going to talk a little bit about putting Ruby onto the command line. You may think, 'Well, that's a silly talk to give because Ruby's already on the command line; you can just call ruby.' But what I want to discuss is really making a very nice shell script that looks like it belongs on the command line and behaves like other command line utilities, like cat.
00:00:14.400
So step zero would be to start writing something. Here, I’m writing a little script that will open up a file. It's going to read each byte and reprint it as if it were binary, and that's what sprint f does. If I were to run this, you can see that it now prints out in ones and zeros. The dollar signs are on there because a new line is not printed; we are just printing ones and zeros.
00:00:33.520
Once you have a simple algorithm like that, the next thing you might want to do is to add options to it. Here, I’m using an option processor to add options and usage information so that you can provide help. It also allows you to loop through ARGV to provide all the file names as command line arguments. You'll notice it still has the same basic algorithm.
00:00:45.439
Now, what this allows you to do is, by passing the -b flag, indicate that you want binary output. It will then read the abc.txt file and the xyz.txt file, printing out their binary representations. To make this a little clearer, I won’t add the -b flag for the remainder of the discussion. Instead, I will just call it and print out the contents, which is essentially the same output as cat would provide for abc and xyz.
00:01:04.960
The next step is to enhance the script's appearance on the command line. This means removing the .rb extension from the file, making the file executable, and adding a shebang line at the top of the file. The shebang line allows your system to look up Ruby and execute it for you, which eliminates the need to type 'ruby' in front of the script when you run it. I’ve made the script executable and now I can use sprint f2 to print out abc and xyz.
00:01:38.640
Next, we need to handle errors gracefully. If I run sprint f2 and attempt to read a missing file, I would normally get a big stack trace revealing all of my contents. Instead of that, I’ll add a `begin` block at the top, followed by a `rescue` block at the end. Now, instead of printing a stack trace, I will just display an error message and exit with status 1, unless debugging.
00:02:05.440
With this change, the error message is much cleaner. If you ever want to restore debugging, you can do so by using ruby -d, which will give you all the stack trace information needed for development. Otherwise, the script will simply show the error message.
00:02:34.000
There are also some other handy features we can add. For example, handling standard input with a dash is a Unix convention. This allows you to specify where you want to read from standard input or other files. In this case, I will read from abc using the dash to indicate standard input, and then do the same for xyz. As you can see, abc and xyz are printed out correctly.
00:03:03.120
To implement this, I’ll check for a dash in ARGV and handle it appropriately. The next step involves ensuring that if ARGV is empty, a dash is added by default. Additionally, if you have a long-running input, like the command yes, you may want to handle interrupts gracefully. Ctrl+C should be able to rescue the interrupt and return 130, which is a standard behavior.
00:03:31.360
You may also want to handle the case where a pipe is closed while your script is running. If you were piping input into Ruby and the stream closes, you would encounter an EPIPE error. To prevent an ugly error message, you can rescue this type of error and exit gracefully with status 0.
00:04:10.560
Another important step is adding your script to the PATH. This way, you won't need to prepend ./ when calling it. By exporting the PATH variable, you make your executable accessible from anywhere in the terminal.
00:04:29.680
The last step is to add manual pages for your script. This enables users to access documentation by using the `man` command. Initially, you may not see your command in the manual pages unless it’s added to the PATH. However, if you successfully add it, you will be able to invoke `man sprint f` to view the manual for your script.
00:05:18.080
In summary, you will find that I have included links to my code on Gist for further exploration. If you are looking into testing shell scripts, you might want to check out the TS project I have been working on. Thank you for your attention.