Run a bash script from source

Introduction

I recently stumbled upon this very simple, but interesting problem. I had the source code for a bash script which I wanted to run in a terminal, on the fly. Think about it from this perspective, you have a bash script being served on cloud somewhere that you would like to run locally. Now you can get that code easily by perhaps using a curl command (curl). The immediate response for anyone familiar with the Linux® terminal a little bit would be to pipe it to bash. Voila!

But here comes the problem. What if you want to pass arguments/options to this script? An obvious question would be: Can’t we simply do curl <destination> | bash <arguments/options>? Experienced terminal users would know that they can’t. I had to find this out the hard way 🙂

This tutorial shows how to pass arguments when trying to run a bash script source in a terminal.

Running a bash script from source

Let’s perform a test, say we create a simple script as follows:


#!/bin/bash
# Stored as test.sh
echo $1

As you can see, this script simply echoes back the first argument to this test.sh script.

Now, to simulate our use case, we can run:
cat test.sh | bash

So far so good. But after running this, we get an empty line echoed back (expected).

The magic to our solution is -s --.

  • -s directs the bash command to read commands from stdin, that is, the terminal.
  • -- is a special delimiter that marks the end of arguments/options to a command. So, anything following this becomes the arguments/options to our test.sh script.

So, our final solution becomes:
cat test.sh | bash -s -- abc

This prints out abc on the next line as expected.

Bonus: You can also pass options to the script in a similar fashion:
cat test.sh | bash -s -- -h

Conclusion

As we’ve seen here, any argument or option can be passed to a bash script source like we would normally do. The only extra step we have to do is pipe the contents into the bash utility and direct it to read arguments from the terminal itself.