shift n переименует переменные $N+1, $N+2, $N+3, … на $1, $2, $3, …

Пример

#!/usr/bin/bash
 
i=1
 
while ! [ -z ${1+x} ]
do
    echo "Here is arg $i: $1"
 
    shift
    i=$((i+1))
done

здесь используем сложную подстановку переменной 1.

В общем виде подстановка ${var+str} работает так:

  • если переменная var не установлена, то подставляется пустая строка ''
  • если переменная var установлена, при этом неважно пустая или нет, то результатом подстановки будет значение str

Подробнее о всяких сложных подстановках можно найти прямо в стандарте: Shell and Utilities: Detailed Toc#2.6.2 Parameter Expansion

Так, условие ! [ -z ${1+x} ] будет возвращать код возарата 0 (всё ок), если в переменной 1 что-то содержится и только в этом случае, во всех остальных случаях условие будет возвращать код возрата 1

Если переменная 1 не установлена, т.е. нет первого аргумента у этого скрипта, то подстановка строки будет пустая строка '' и тогда [ -z ${1+x} ] вернёт код возврата 0, а ! [ -z ${1+x} ] соответственно 1.

Пользуемся этим и на каждой итерации работаем с первым аргументом, а в конце вызываем shift без аргументов, он переименует аргументы $2, $3, ... в $1, $2, ...

Таким образом скрипт обойдёт все переданные аргументы и выведет их по одному, добавив префикс Here is arg n: перед выводом каждого аргумента n.