Skip to content

Instantly share code, notes, and snippets.

@magnetikonline
Last active August 28, 2018 00:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save magnetikonline/8608fdba9aa324141e268a01b68799a4 to your computer and use it in GitHub Desktop.
Save magnetikonline/8608fdba9aa324141e268a01b68799a4 to your computer and use it in GitHub Desktop.
Bash shift quirks.

Bash shift quirks

When using the shift built-in, have noted this interesting behavior which I have been unable to find documentation for.

Update: the answer was right in front of me, if shift is called with a value greater than arguments available in $1 - $x then it will return with a non zero status - hence the script will halt (since I'm using set -e)!

Using the script test.sh, executed using arguments:

./test.sh apple orange banana
apple
orange
banana

banana


red
blue

As expected:

  • Three arguments echoed.
  • Shift two away.
  • One remains as $1 (banana).

And then without arguments:

./test.sh

# no output

Arguments $1 - $3 don't exist, so no output or shift but $variable1 and $variable2 are now broken!?!

Why? I'm not sure. Appreciate any comments!

But what this does show, it's safer to check the number of positional arguments available before calling shift e.g.:

[[ $# -ge 2 ]] && shift 2

Reference

#!/bin/bash -e
echo "$1"
echo "$2"
echo "$3"
echo
shift 2
variable1="red"
variable2="blue"
echo "$1"
echo "$2"
echo "$3"
echo "$variable1"
echo "$variable2"
@bambam2174
Copy link

bambam2174 commented Aug 26, 2018

The reason for that behaviour ist the -e option in #!/bin/bash -e
It's like calling set -e which has the effect that a script exits immediately if any command exits with a non-zero status.
And if you shift more than the arguments / parameter count then the shift-command exits with a non-zero status.
That prevents executing any further commands after this shift-call.
If you omit the -e option at the beginning the following commands (echos) will get executed

@magnetikonline
Copy link
Author

magnetikonline commented Aug 27, 2018

Of course @bambam2174 - and to be honest, that answer was right in front of me!!! 🤦‍♂️

See here http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_07.html (which I linked to as well!).

The return status is zero unless N is greater than $# or less than zero; otherwise it is non-zero.

That was my own silly fault 🤕 - thanks for setting me right!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment