10

The following script works fine in one of my machines, printing 1 then 2:

#!/bin/sh

echo "1"
shift
echo "2"

On another machine, however, it produces the following output:

1
./script.sh: 4: shift: can't shift that many

man shift does not help (No manual entry for shift).

What is that error, why is it happening, and how can I fix it?

anol
  • 1,741

1 Answers1

13

What is shift: it is a shell built-in that works as follows (adapted from TLDP):

The shift command takes one argument, a number (if not present, it is assumed to be 1). The positional parameters (e.g. command arguments) are shifted to the left by this number, N. The positional parameters from N+1 to $# are renamed to variable names from $1 to $# - N+1.

Often you make a loop in which you process one or more arguments, then you call shift to "forget" them and loop again to process the following ones.

Error cause: The error comes from the fact that some shells (but not all) detect when there are not enough arguments for shift. In particular, dash considers it a fatal error.

Possible solutions:

  • Test if there are enough remaining arguments: if [ "$#" -gt 0 ]; then shift; fi

  • Add a conditional argument: shift $(( $# > 0 ? 1 : 0 ))

anol
  • 1,741
  • Just stumbled across this when I had the same problem. Thanks for posting this Q&A! You can also accept your own answer (that's considered perfectly acceptable, ba-dum-tss). (There's a two-day delay before you can accept your own answer, but I think it's safe to say that's elapsed by now.) ;) – n.st Dec 08 '18 at 14:27
  • let $# && shift aka (( $# )) && shift is another form of conditionally doing a shift. If i understand it correctly, the double parenthesis (or: two parentheses, or: two round brackets) are the same as the command let which allows for arithmetic evaluation. And let 0 (or: (( 0 ))) evaluates to a non-zero exit. – immeëmosol May 25 '22 at 10:16
  • 1
    Or maybe a bit different.. The POSIX-version seems to be test $(( $# )) && shift as ((& let seem not to be in the standard. perhaps relevant: https://github.com/koalaman/shellcheck/wiki/SC2219 . – immeëmosol May 25 '22 at 11:47