0

I'm trying to dynamically delete elements from an array in bash based on a script argument of the form '123' where each single digit number in the argument is assumed to be an index of the array which should be removed.

#!/bin/bash
# Doesn't delete an element.
ARRAY=(a b c)
while getopts ":a:" opt; do # run e.g. 'thisscript.h -a 0'
    case $opt in
        a)
            echo -n $OPTARG |\
                while read -n 1 c; do
                    unset ARRAY[$c]
                done
                ;;
    esac
done
echo ${ARRAY[@]}
# Deletes an element successfully.
ARRAY=(a b c)
unset ARRAY[0]
echo ${ARRAY[@]}
# Deletes an element successfully.
ARRAY=(a b c)
n=0
unset ARRAY[$n]
echo ${ARRAY[@]}

Write this to e.g. tmp.sh file, chmod +x tmp.sh to make executable, then run 'tmp.sh -a 0'.

Why doesn't the first array element deletion method work, and how can I make it work within the 'read -n 1' context?

1 Answer 1

1

The problem is the PIPED while-read loop which runs as a subshell. Therefore, the unset occurs in a subshell and disappears when the subshell exits. That's why there is no effect on the array variable.

This problem is described in Section 20.2. Redirecting Code Blocks of the Advanced Bash-Scripting Guide.

Here is one workaround, using process substitution instead of a pipe.

while read -n 1 c; do
    unset ARRAY[$c]
done < <(echo -n $OPTARG)
Sign up to request clarification or add additional context in comments.

2 Comments

How interesting - thanks very much for the explanation dogbane. I'd like to understand the usage of double '<' in your example, but can't find the string '< <' in the page you linked to. Is there a name for the construct that I can Google to find out more?
<(...) syntax is called process substitution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.