1. Overview

When fetching Bash scripts using the cURL command, we may sometimes want to include arguments in the shell script call.

In this tutorial, we’ll learn different ways to pass arguments to a shell script fetched by cURL. Initially, we’ll see how we can do that by using query parameters. Furthermore, we’ll discuss environment variables and standard input for passing arguments to a shell script along with the curl command.

2. cURL Command Overview

The curl command is a versatile tool for making URL requests and retrieving data. The syntax of the curl command consists of options and a URL:

curl [options] [URL]

Since we’ll be fetching a Bash script for this tutorial, we’ll also directly pass the output to the bash command for execution:

curl [options] [URL] | bash

In this case, the curl output is technically the content inside the script, so we pipe that to bash. Since curl may also add some additional information, we’ll pass the -sSL options to secure the command and suppress its output:

curl -sSL [options] [URL] | bash

In particular, the -sSL options indicate silent, secure, and follow-redirects execution.

The example script we use is at URL http://0.0.0.0:8080/cgi-bin/script.sh.

Finally, we may also employ the -s option of bash to specifically indicate we’ll be reading commands from stdin.

3. Pass Arguments Directly to bash

Since the bash command supports it, we can use the operator to separate the script arguments:

$ curl -sSL http://0.0.0.0:8080/cgi-bin/script.sh | bash -s -- value1 value2

In this example, the arguments are passed as positional parameters, so the value of the first argument is value1, while the value of the second is value2.

This syntax ensures we separate the curl command output from the arguments passed to the shell script. In addition, the -s option indicates stdin or script, which means that bash reads the script content from the standard input stream instead of a script file path that we can pass in. Also, the delimiter separates the bash command options from the positional arguments.

Importantly, proper quoting should take place when dealing with argument values containing whitespace:

$ curl -sSL http://0.0.0.0:8080/cgi-bin/script.sh | bash -s -- "a value" "another value"

Here, we see two arguments are passed instead of four (words).

Within the script, we access the argument variables $1 and $2 as usual:

$ cat script.sh
#!/bin/bash
echo "Argument 1: $1"
echo "Argument 2: $2"

If we need more arguments, we can also use $3$4, and so on. Finally, we can also employ the $@ arguments array.

4. Use Environment Variables to Pass Arguments

Another method to pass arguments to a shell script fetched by the cURL command is environment variables. To elaborate, we set the arguments in environment variables before executing the script. After that, the script can access those arguments via the variables.

First, we’ll set environment variables before fetching the script. For this step, we’ll use the export command:

$ export ARG1=value1
$ export ARG2=value2

If we don’t export the variables, a script, even if it’s in a subshell of the current one, wouldn’t be able to access them.

Next, we’ll fetch our shell script using cURL:

$ curl -sSL http://0.0.0.0:8080/cgi-bin/script.sh | bash

The output of the script located at https://example.com/script.sh is piped to the bash command for execution.

Now, we can access the arguments inside the shell script via the variable names:

$ cat script.sh
#!/bin/bash
echo "Argument 1: $ARG1"
echo "Argument 2: $ARG2"

On the other hand, we can pass the environment variables as arguments while fetching the script:

$ curl -sSL http://0.0.0.0:8080/cgi-bin/script.sh | ARG1=value1 ARG2=value2 bash

The values are assigned to the ARG1 and ARG2 variables respectively. Again, we should adhere to proper quoting.

Importantly, this way of passing arguments has a couple of benefits:

  • arguments have names, which might suggest their function
  • when starting the script, we already have the proper variables set, so we don’t need to assign positional variables

Still, exporting does affect the environment, so, if we choose this option, it’s usually better to supply arguments as a prefix to the bash command.

5. Standard Input (stdin) Method

With this approach, the arguments are passed as a here-document. A here-document is a special code block that contains multiline strings. Thus, we can redirect it to our bash command.

After that, we access and process the arguments inside the script using any standard input-handling technique.

To elaborate, we fetch the shell script first as described earlier. After that, we provide the arguments to that shell script using the input redirection operator. For instance, let’s use a basic format to pass two arguments:

$ curl -sSL http://0.0.0.0:8080/cgi-bin/script.sh | bash << EOF
ARG1=value1
ARG2=value2
EOF

Here, we’ve provided the arguments as a here-document with each line containing a key-value pair. The input format is arbitrary, but we must know it to process the arguments properly. In this way, the script can access the arguments using the read command or by reading from file descriptor 0, i.e., stdin.

After that, script.sh can parse the arguments:

$ cat script.sh
#!/bin/bash
while IFS='=' read -r key value; do
  declare "$key=$value"
done
echo "Argument 1: $arg1"
echo "Argument 2: $arg2"

We’ve used a while loop to read each line from the standard input. Furthermore, we’ve changed the value of IFS to parse each line by splitting it at the equals sign (=). In addition, we employ the declare command to create variables from each key-value pair of the passed arguments. Lastly, we use the echo command to display the output.

6. Pass Arguments to a Shell Script From a File

Alternatively, we can also pass the arguments via a file. For instance, we’ll again store arguments in key-value pair format as a text file called arguments.txt:

$ cat arguments.txt
ARG1=value1
ARG2=value2

Then, we’ll fetch the script using the cURL command and pass the contents of arguments.txt using the input redirection operator:

$ curl -sSL http://0.0.0.0:8080/cgi-bin/script.sh | bash < arguments.txt

The content of the script should contain the code to parse and utilize the arguments using standard input as we’ve discussed in the earlier example.

7. Conclusion

In this article, we’ve learned several methods to passing arguments to a shell script fetched by the cURL command.

First, we discussed how we can pass arguments directly to bash. After that, we used environment variables to store argument values. Next, we learned how standard input can achieve the same. Finally, we saw that files can also store our argument values.

We can opt for any method depending on our requirements. However, we must ensure that the source of the script is trusted and validated before passing it for execution.