Does your script accept a variable number of arguments? To easily process each argument, bash has shift command. The command allows you to shift the positional parameters passed to a script.
In this tutorial, we learn about bash shift command with examples.
shift Command
Shift is a commonly used Linux built-in command that comes with Bash. As the name suggests, we use this utility to shift the positional parameters to the left. As we shift left, the first argument gets lost during the process and puts each parameter in a lower position. This is a handy tool to have, to discard the arguments which are not required after they are parsed.
The shift operator shifts the current positional parameters ‘c’ times towards the left. During this process, the current positional parameter is assigned the value of the parameter ‘c’ places ahead of it. If ‘c’ is not specified, it is left shifted by 1. c can be specified as zero as well. If done, the command will execute but the shifting of the arguments will not take place.
Assuming there is a script accepting 10 arguments, a shift 4 will result in the following:
- Older $1, $2 and $3 are discarded
- Older $4 becomes $1
- Older $5 becomes $2
- Older $5 becomes $3
- Older $10 becomes $7
Here’s the syntax:
shift <c>
Shift command takes just one non-negative optional argument ‘c’ which determines the number of positions the parameters should be left shifted. If c is passed as 0, no parameters are shifted. c has a default value of 1. c cannot be a negative number.
Bash shift examples
Let's look into some practical examples of bash shift.
Read all arguments
We can read all the arguments passed to the script using a while loop with the help of the shift command.
Example:
#!/bin/bash
while test $# -gt 0
do
echo "Argument 1 is now $1"
shift
done
Run the script as follows:
./shiftScript1.sh 1 2 3 4 5 6 7 8 9
In this example, we are reading one argument at a time while iterating all the arguments over a while loop and making use of the shift command. The arguments list is treated like a queue. Each shift removes the first argument out and the index of each of the remaining arguments is decremented. We continue to do this until the total count of the arguments($#) runs out.
Shift by a specific number
We can use the shift tool to do a left shift by a non-negative integer.
Example:
#!/bin/bash
echo "Current values of parameter 1 and 2: " $1 and $2
shift 3
echo "After 3 shifts: " $1 and $2
shift 0
echo "After 0 shift: " $1 and $2
Run the script as follows:
./shiftScript2.sh 1 2 3 4 5 6 7 8 9
In the above example, $1and $2 hold the values 1 and 2 respectively.After 3 shifts, $1 will be storing 4 and $2 will have a value of 5. A shift by zero will result in the variables holding the same value and there won’t be any change.
Using shift with arrays
We can use shift with arrays using the set command. It allows us to set the positional parameters, or to display the names and values of shell variables.
Example:
#!/bin/bash
arr=("a" "b" "c") #array
set -- ${arr[@]}
while [ $# -gt 0 ]
do
echo "$1"
shift
done
The variable [email protected] gives the array of input parameters, and $# returns the size of that array. In the example, the array is supplied to the set command. After that, we are running a while loop till the number of positional parameters which have been set by the set command. In the first iteration we get the first array element. After this we shift which makes the array length decrease by 1. We continue to do so till the count is greater than zero.
Pass the First argument to function
Using the shift utility we can pass the argument to the function.
Example:
#!/bin/bash
func() #function to convert to UPPERCASE
{
echo $1 | tr [:lower:] [:upper:]
}
while test $# -gt 0
do
func() $1
shift
done
Run the script as follows:
./shiftScript4.sh athens rome paris warsaw berlin lisbon
In this example we have written a function that takes a string as an input and converts it into uppercase. This function is used inside the while loop along with the shift command. In every iteration the argument will be passed to the function which converts it to uppercase and prints it on the screen. Then there will be a left shift. This will continue until all the arguments are processed.
Using shift with getopts
The Bash built-in command getopts helps to gracefully retrieve the options and the option arguments from a list of parameters. It is used to break up the options in command lines for easy parsing.
Example:
#!/bin/bash
while getopts ":a:bc" opt
do
case $opt in
a) echo "$OPTARG" ;;
b) echo "$0 [-b] [-a A] [-c] C..."; exit;;
c) echo $OPTIND ;;
\?) echo "Invalid option: -$OPTARG" >&2 ;;
esac
done
shift "$((OPTIND-1))" # shift so that [email protected], $1, etc. point to the non-option arguments
The script only takes the flags -b and -c, and also accepts -a with an argument. It can accept any number of positional arguments. To access these positional arguments, we make use of shift "$((OPTIND-1))". The OPTIND gives the index of the next command line argument. This shift makes sure that [email protected] and the other inputs point to the positional arguments and not the option arguments.
After the while loop is over, it is important to run the shift so that it performs the shuffling of the positional parameter. This allows the script to execute correctly by shifting the options away. This ensures the processing of the command line arguments.
Conclusion
- Bash shift command shifts the positional parameters to the left.
- This command always discards the previous value of $1
- We can use shift inside a while loop to read all the arguments one by one.
- Shift can be even used on arrays.
Comments