Bash unshift: prepend to arrays, shift, and pop (with examples)

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:

bash
fruits=(apple banana cherry)
fruits=(orange "${fruits[@]}")
printf '%s\n' "${fruits[@]}"
text
orange
apple
banana
cherry

Prepend several at once:

bash
nums=(1 2 3)
prefix=(x y z)
nums=("${prefix[@]}" "${nums[@]}")
echo "${nums[*]}"
text
x y z 1 2 3

If 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:

bash
people=(Dave Alice Bob Carol)
people=("${people[@]:1}")
printf '%s\n' "${people[@]}"
text
Alice
Bob
Carol

That is the array analogue of “shift off the front”. Do not write shift peopleshift 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):

bash
set -- one two three
echo "before: $*"
set -- zero "$@"
echo "after:  $*"
text
before: one two three
after:  zero one two three

Remove the first positional:

bash
set -- a b c
shift
echo "$*"
text
b c

For 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+:

bash
stack=(1 2 3)
unset 'stack[-1]'
echo "${stack[*]}"
text
1 2

Alternatively, slice up to length minus one:

bash
a=(1 2 3)
a=("${a[@]:0:$((${#a[@]} - 1))}")
echo "${a[*]}"
text
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.

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)