无法使用“read -n 1”删除数组元素字符作为数组索引

发布于 2024-12-25 19:42:52 字数 698 浏览 1 评论 0原文

我试图根据“123”形式的脚本参数从 bash 中的数组中动态删除元素,其中参数中的每个单位数字被假定为应该删除的数组的索引。

#!/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[@]}

将其写入例如 tmp.sh 文件,chmod +x tmp.sh 使其可执行,然后运行“tmp.sh -a 0”。

为什么第一个数组元素删除方法不起作用,如何使其在“read -n 1”上下文中工作?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅沫记忆 2025-01-01 19:42:52

问题是作为子 shell 运行的 PIPED while-read 循环。因此,unset 发生在子 shell 中,并在子 shell 退出时消失。这就是为什么对数组变量没有影响的原因。

第 20.2 节描述了此问题。高级 Bash 脚本指南的重定向代码块

这是一种解决方法,使用进程替换而不是管道。

while read -n 1 c; do
    unset ARRAY[$c]
done < <(echo -n $OPTARG)

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文