Heroku provides a convenient command line interface for executing snippets of Ruby code remotely. One-liners can easily be piped into the
heroku run console command. But what about much longer scripts that you write locally and want to execute in a remote Heroku environment? In this post, I’ll show you how to execute a long Ruby/Rails script in a remote Heroku environment.
run console command will read input from
stdin and pass it to the remote console session. Knowing this, you can run a simple Rails query:
echo "puts User.count" | heroku run console --app=my-heroku-app
The result will be displayed in the terminal, but you’ll still be in the Heroku console session. One way to avoid that would be to force the session to end by tacking on an
exit to your one-liner.
echo "puts User.count; exit" | heroku run console --app=my-heroku-app
Now the result is displayed, and the console session exits immediately.
I wanted to run a much longer script (several thousand lines) using this same technique, but whenever I’d try, it would always hang part-way through the script, never completing.
My teammate Brian Vanderwal pointed out the
--no-tty argument, and that did the trick! By including that argument, I can pipe (or redirect) an arbitrarily long Ruby script into a Heroku console. And as an added bonus, when you specify the
--no-tty argument, you no longer need the
exit at the end.
echo "puts User.count" | heroku run console --app=my-heroku-app --no-tty
cat some_script.rb | heroku run console --app=my-heroku-app --no-tty
For years, I’ve known about the ability to run scripts that are checked into the repository using the
heroku command line tool.
heroku run bundle exec rails runner ./scripts/script.rb -a my-heroku-app
But there are some cases where you want to execute code in the production environment without doing a full production deploy first. In those cases, the
--no-tty argument to the
heroku run console command is exactly what you need.