There is no unshift builtin in Bash. Unshifting still means “prepend one or more elements”; you implement that by rebuilding the array or by resetting positional parameters with set --. shift only moves positional parameters ($1, $2, …)—it does not take an array name. For shifting a normal indexed array, slice off index 0 instead.
Tested the snippets below with GNU Bash 5.2.37 on Linux (2026-06-14).
bash prepend to array (simulate unshift)
Prepend one element:
fruits=(apple banana cherry)
fruits=(orange "${fruits[@]}")
printf '%s\n' "${fruits[@]}"orange
apple
banana
cherryPrepend several at once:
nums=(1 2 3)
prefix=(x y z)
nums=("${prefix[@]}" "${nums[@]}")
echo "${nums[*]}"x y z 1 2 3If the data starts as a string, split first (see split a string into a Bash array), then prepend as above.
bash array shift (remove the first element)
To drop the first element of an indexed array, use a sub-array starting at index 1:
people=(Dave Alice Bob Carol)
people=("${people[@]:1}")
printf '%s\n' "${people[@]}"Alice
Bob
CarolThat is the array analogue of “shift off the front”. Do not write shift people—shift only affects $@ / $* in the current shell or function.
bash shift array: positional parameters
shift (and shift n) removes the first n positional parameters and renumbers the rest. set -- replaces $@ entirely.
Prepend to $@ (positional unshift):
set -- one two three
echo "before: $*"
set -- zero "$@"
echo "after: $*"before: one two three
after: zero one two threeRemove the first positional:
set -- a b c
shift
echo "$*"b cFor option parsing patterns, bash script multiple arguments and script arguments in Bash stay the usual references.
shift vs unshift
| Idea | Array form | Positional form ($@) |
|---|---|---|
| Unshift / prepend | arr=(new "${arr[@]}") |
set -- new "$@" |
| Shift / drop front | arr=("${arr[@]:1}") |
shift (or shift n) |
Shift vs unshift is only about direction: shift consumes the head; unshift prepends a new head.
bash pop argument (remove the last element)
Bash has no pop builtin either. For indexed arrays, unset 'arr[-1]' drops the last element on Bash 4.3+:
stack=(1 2 3)
unset 'stack[-1]'
echo "${stack[*]}"1 2Alternatively, slice up to length minus one:
a=(1 2 3)
a=("${a[@]:0:$((${#a[@]} - 1))}")
echo "${a[*]}"1 2“Pop” for $@ is rarer; often you copy positional parameters into an array, pop from the array, then set -- "${array[@]}" if you need to continue with a new $@.
Summary
Prepending in Bash means: arr=(item "${arr[@]}") for arrays, set -- item "$@" for positional parameters. “bash shift array” wording usually maps either to shift on $@ or to arr=("${arr[@]:1}") on a real array—never shift arrayname. Shift vs unshift is remove-first versus add-first. For removing the last element, use unset 'arr[-1]' on modern Bash or a length-based slice. Details and edge cases (sparse arrays, set -u) live in the GNU Bash manual under Shell Parameters and Arrays.
For removing items between arrays, see delete elements of one array from another.

