Argument in Bash Script

Proper execution of a Bash script depends on the successful parsing of its arguments. After parsing the arguments users need to access those using the correct syntax within the script. Bash allows the manipulation of command line arguments passed to a script. But figuring out how to do this in a Bash script can sometimes be tricky. In this article, I will discuss all the concerns Bash users have about arguments in a script.

Syntax for Passing Arguments to Bash Script

To pass arguments to a Bash script, simply list them after the script’s name when invoking the script from the terminal. For example:

./script.sh arg1 arg2 arg3

Here, arg1, arg2 and arg3 are three arguments passed to the script named script.sh.

How to Access Arguments in Bash Script

There are a couple of ways to access arguments passed to a Bash script. Most Bash users utilize positional parameters to process arguments in a script. Though less popular, the getopts command to access command line arguments is equally handy.

1. Using Positional Parameters

Arguments passed to a script can be accessed using positional parameters like $1, $2, $3, etc. These parameters correspond to the first, second, third and subsequent arguments provided to the script. Look at the example below to understand how it works:

#!/bin/bash
echo "Hello $1. Welcome to LinuxSimply"
EXPLANATION

The script prints a message in the terminal using the echo command. It uses $1 (first positional parameter) to access the argument provided to the script.

Accessing argument in Bash script using positional parameterRunning the script with the argument “Anita” replaces $1 with “Anita” within the script.

2. Using “getopts” Command

The getopts command with OPTAG environment can process command line options and arguments. One can provide single or multiple arguments under an option using the getopts command. Here is an example of how getopts handle arguments in Bash script:

#!/bin/bash

while getopts "n:i:" opt;
do
  case "${opt}" in
    n) processname=${OPTARG};;
    i) id=${OPTARG};;
  esac
done

echo "processname: $processname";
echo "processid: $id";
EXPLANATION

This Bash script utilizes the getopts command to parse command-line options and arguments. It expects two options: -n, which takes an argument called processname, and -i, which takes an argument called id.

Inside a while loop, it uses a case statement to handle each option. When -n is encountered, it assigns the following argument to the “processname” variable. On the contrary, when -i is encountered, it assigns the following argument to the “id” variable. After parsing the options, it prints out the values of “processname” and “id”.

Accessing argument in Bash script using the getopts commandWhile invoking the script, the argument “firefox” is provided after -p option and -i receives the argument 1290. The script accesses both arguments using the variables defined in the case statement.

How to Check the Number of Arguments in Bash Script

Use the special variable $# to check the number of arguments passed to a script. This variable is used for storing the number of command-line arguments. If there is no argument, then the value of $# will be 0. Here is an example:

#!/bin/bash
echo "Total number of arguments: $#"

Getting number of arguments passed to a scriptExecuting the script with no argument shows that the total number of arguments is 0. However, when “arg1”, “arg2” and “arg3” are provided the script displays that the number of arguments is 3.

How to Get All the Arguments Passed to a Script

To get all the arguments passed to a script, use the special variables S@ or S*. These two variables contain the array of all input parameters provided to a script. However, the value of these variables may differ depending on whether they are quoted or not.

1. Utilizing $@ to Get All Command Line Arguments

The $@ variable holds all the arguments passed to a script. Therefore, it is used to get all the command line arguments. Here’s how:

#!/bin/bash
echo "Arguments provided to the script: $@"

Getting all the command line argument of a Bash scriptarg1, arg2 and arg3 are three arguments provided while executing the Bash script. The image confirms that $@ correctly captures and displays all the command-line arguments passed to the script.

Double-quoted (“$@”) and unquoted ($@) may behave differently. “$@” expands to an array of separate strings containing the arguments. On the other hand, $@ splits the input arguments into words separated by space (Or based on the first field of the IFS variable). The difference is visible when you iterate over the input arguments using a for loop:

#!/bin/bash

# Using $@
echo "Using \"\$@\":"
for arg in $@; do
  echo "$arg"
done

# Using "$@"
echo "Using \"\$@\":"
for arg in "$@"; do
  echo "$arg"
done
EXPLANATION

This Bash script demonstrates the difference between using $@ and “$@” by iterating over the command-line arguments.

In the first loop, $@ is used without quotes, causing word splitting to occur. By default, words are separated by space. Hence a single argument can be separated into multiple words if it contains space.

In contrast, the second loop uses "$@" with double quotes, preserving each argument as a separate string. This ensures that arguments containing spaces or special characters are treated as single units.

Difference between quoted and unquoted $@$@ causes the arguments arg1, “arg 2” and arg3 to split into four different words. Because there is a space in the second argument. However,  when quoted “$@” expands to three different arguments as provided to the script.

2. Utilizing $* to Get All Command Line Arguments

Similar to $@, $*  is used to get all the command line arguments.

#!/bin/bash
echo "Arguments provided to the script: $*"

Getting all command line arguments$* retrieves all the argument three arguments a,b and c provided to the script.

Again, double-quoted and unquoted $* behave differently. “$*” expands to a single string. On the contrary, $* splits into words separated by space (Or based on the first field of the IFS variable). Let’s visualize the difference using a for loop:

#!/bin/bash

# Using "$*"
echo "Using \"\$*\":"
for arg in "$*"; do
  echo "$arg"
done

# Using $*
echo "Using \$*:"
for arg in $*; do
  echo "$arg"
done
EXPLANATION

This Bash script illustrates the difference between using “$*” and $* to iterate over command-line arguments.

In the first loop, double-quoted “$*” causes all command-line arguments to be expanded into a single string. Consequently, the loop iterates only once, printing all arguments as a single string. Conversely, in the second loop, $* is used without double quotes, causing word splitting to occur. Hence, any separation by space in the arguments is treated as a separate word, leading to one more iteration of the loop.

Difference while gettting all arguments of a bash scriptAs expected “$*” prints all the arguments arg1, “arg 2” and arg3 in a line as single string. But $* splits the arguments into four different words.

What is the Difference Between “$@” and “$*”

The main difference between “$@” and “$” is that “$@” expands to a string for each command line argument. Whereas “$*” expands into a single string with all of the words parsed as arguments. This is easy to understand with the following example:

#!/bin/bash

# Using "$@"
echo "Using \"\$@\":"
i=0
for arg in "$@"; do
  echo "$arg"
  ((i++))
done
echo "Loop runs $i times"

# Using "$*"
echo "Using \"\$*\":"
j=0
for arg in "$*"; do
  echo "$arg"
  ((j++))
done
echo "Loop runs $j times"
EXPLANATION

In the first for loop the script iterates over command line arguments using “$@”. It initializes a counter i to track the number of iterations. It proceeds to traverse each argument individually through a for loop, printing each argument and incrementing i accordingly. Finally, the script outputs the total number of iterations, reflecting the count of command-line arguments.

In the second portion, it program uses “$*” to iterate over arguments. This time it initializes a counter j. Again the script attempts to print each argument stored in  “$*” while incrementing j in each iteration.

Difference while gettting all arguments of a bash scriptHere, the arguments provided to the script are arg1, “arg 2” and arg3. "$@" expands to an array of three elements each containing the arguments provided to the script. Hence, when iterating over “$@”, the loop runs three times, each time accessing one of the arguments.

On the other hand, "$*" expands to a single string containing all the arguments concatenated together. Therefore, when iterating over “$*”, the loop runs only once since there is only one element in the array.

How to Shift Command Line Arguments in Bash Script

Shifting command-line arguments in a Bash script allows you to access subsequent arguments by adjusting their positional index. The shift command is used for this purpose. After calling shift, the $1 will be the value of $2, $2 will be the value of $3 and so on. The following script demonstrates the shifting of command line arguments:

#!/bin/bash

echo "First Argument: $1"
shift
echo "Second Argument: $1"

Shifting argument to the left by 1After the shift command, $1 retrieves “arg2” which is the second argument provided to the script.

Moreover, one can provide a number as an argument to the shift command. shift n (n is the number) causes the positional parameters to be shifted left by n positions. For instance, shift 3 causes the fourth argument to become accessible by $1, and the fifth argument becomes accessible by $2 and so on.

#!/bin/bash

echo "First Argument: $1"
shift 3
echo "Fourth Argument: $1"

Shifting argument by n position to the left using shift commandAfter shifting the command line arguments by 3, $1 can retrieve the fourth argument which is 14.

How to Change Command Line Arguments in Bash

In a Bash script, you can change command-line arguments by assigning them to variables within the script. This approach allows you to manipulate the arguments without directly modifying them. Here’s an example:

#!/bin/bash

# Assign command-line arguments to variables
arg1=$1
arg2=$2

# Modify the first argument
arg1="Nan"
echo "Modified first argument: $arg1"
EXPLANATION

This script assigns the first two command-line arguments to variables arg1 and arg2. It then modifies the value of “arg1” by assigning it the string “Nan”. Finally, it prints the modified value of “arg1”.

Changing argument using variable within a scriptThe first argument provided to the script is 75. But after taking it in a variable the script modifies the value of the variable to “Nan”.

The set command provides a direct way to modify the command line arguments. The following script shows how the set command can be used to update the arguments:

#!/bin/bash

# Update the arguments as required
set -- "${@:1:2}" "Nan" "${@:4}"

# Display the updated arguments
echo "Updated arguments: $@"
echo "Third argument: $3"
EXPLANATION

This script updates the arguments passed to it by replacing the third argument with “Nan” while preserving the first two arguments and those from the fourth onwards. It achieves this by using the set -- command to redefine the entire argument list. The ${@:1:2} syntax selects the first two arguments, and ${@:4} selects all arguments from the fourth position onwards, effectively excluding the third argument. “Nan” in the middle sets the new value of the third argument.

Finally, the script echoes the updated arguments using $@ and displays the third argument separately using $3.

Changing command line argument uisng set commandThe image shows that the third argument has been changed from 3 to “Nan”.

Practice Tasks on Bash Script Argument

Write a bash script named myscript.sh that takes 10 arguments as follows:

./myscript.sh a b c "arg 3" x 10 15 32 y z
  1. Echo the first and last argument using positional parameter?
  2. Change the fifth argument to “Null” and access it using positional parameter $5?
  3. Shift the arguments so that you can access the last argument using the first positional parameter ($1)?
  4. Print all the arguments using $@ and $*?
  5. Use a for loop to iterate over “$@” and “$*”. Determine how many times the loop runs?

Conclusion

In conclusion, Bash provides various methods for accessing and modifying arguments passed to a script. Positional parameters serve as the default choice for this purpose. Additionally, special variables such as “$@” or “$*” allow users to examine all command-line arguments. Furthermore, the process of shifting command-line arguments enables users to alter the positional index of arguments. Finally, the set built-in allows direct modification of command-line arguments within the script

People Also Ask

What is the meaning of $0 in the Bash shell?

The special variable $0 refers to the name of the script that is currently being executed. For example, if you run a script named myscript.sh using the command ./myscript.sh, then within the script, the value of $0 would be myscript.sh.

How to access command line arguments after the first 9 positional parameters?

To access command line arguments beyond the first 9 positional parameters in a bash script, you can use ${10}, ${11}, and so on. This allows you to access arguments beyond the positional parameters 0 through 9. Don’t use $10 without curly braces. This will expand to the first positional parameter($1) and then add the literal 0 after the expansion.

Which one should I prefer between “$@” and “$*” to get all the arguments?

To get all command line arguments in a bash script, “$@” is generally preferred over “$*”. Because “$@” treats each command-line argument as a separate entity. While “$*” expands to a single string containing all the arguments.

How to pass a file as an argument to a bash script?

To pass a file as an argument to a Bash script, you would typically provide the filename as an argument when running the script from the command line. Here’s how you can do it:

./script.sh filename.txt

To access the contents of the file inside the script use the corresponding positional parameter:

data=$1

Why “argument list too long” error occur in Bash?

The “argument list too long” error occurs in Bash when someone attempts to pass a large number of arguments to a bash script or a command that exceeds the predefined argument limit of the system. The limit is typically around 100,000 arguments. This limit is imposed to prevent memory overflow and ensure system stability.

Related Articles


<< Go Back to Bash Functions | Bash Scripting Tutorial

Rate this post
LINUX
FUNDAMENTALS
A Complete Guide for Beginners Enroll Course Now
Md Zahidul Islam Laku

Hey, I'm Zahidul Islam Laku currently working as a Linux Content Developer Executive at SOFTEKO. I completed my graduation from Bangladesh University of Engineering and Technology (BUET). I write articles on a variety of tech topics including Linux. Learning and writing on Linux is nothing but fun as it gives me more power on my machine. What can be more efficient than interacting with the Operating System without Graphical User Interface! Read Full Bio

Leave a Comment