Ruby script equivalent to the linux `set` command's `-x` flag?
When a bash script is running, the set -x
command can be used to print all commands and output as they're being executed.
I'm writing a Ruby script. Is there a way to also have this print the commands and output as they're being executed?
TL;DR
While interpreted, Ruby parses and runs code very differently from languages like Bash or Tcl, so there's no built-in way to do exactly what you want. You'll have to use a debugger or REPL to get something that approximates what you're trying to do, but it won't really be the same as using flags like -x
or -v
in Bash. An external or IDE-based debugger will probably come closest, though.
A Couple of Options
There is no built-in way to do this, as Ruby is not really a line-by-line interpreted language in the same way as Bash or Tcl. While Ruby is generally considered an interpreted language, it actually uses a tokenizer and parser to generate code that runs on a virtual machine such as YARV or GraalVM. You do have a couple of options, though:
-
Use the
-d
flag or set$DEBUG
to a truthy value in your code, and then do some level of introspection based on whether the debug flag is enabled. For example:# 1 is printed because $DEBUG is truthy $ ruby -e 'BEGIN { $DEBUG = true }; puts 1 if $DEBUG' 1 # nothing is printed because $DEBUG is falsey $ ruby -e 'puts 1 if $DEBUG'
Please note that Ruby 3.0.3 and 3.1.0 seem to have an issue with the
-d
flag, so the first example uses a BEGIN statement to set the value of the flag inside the program. -
Use the debug gem (now standard with Ruby 3). You can either step through the code with rdbg and use the
list
command liberally, or (if you're clever) script a series of list commands on specific lines using the~/.rdbgrc
file. -
Use an external debugger, with or without rdbg. Note that the new debugger supports IDE-based debugging (e.g. with RubyMine or VS Code) and remote debugging, but setting up IDE or remote debugging is likely a topic outside the scope of a reasonable SO answer.
-
Use irb or pry with the debugger of your choice, which usually gives you a number of ways to inspect source code, frames, expressions, variables, and so on, although you need to run from an on-disk file rather than a REPL to access some of the functionality you may be looking for.
For the most part, if you're not using an IDE or a debugger, you will generally need to rely on return values in a REPL or Kernel#pp
statements in your code to inspect return values as you go along. However, short of a debugger or REPL that supports listing methods or lines of code on request, you'll either need to use external tools to solve whatever problem you're trying to solve via this approach another way.
Other Options
If you use pry, the pry-rescue gem along with pry-stack_explorer will allow you to automatically trigger a REPL session that allows you to traverse up and down the stack if you hit an exception without requiring you to start your session in the REPL or explicitly call binding.pry
. On supported versions of Ruby, this can be very useful, especially since Pry supports a show-source -l
command that will do something similar to what you want (at least interactively), although the line numbers may not be what you expect if the code is entered directly in the REPL rather than loaded from a Ruby program on disk.