Arrays 为什么在bash中取消设置数组的第一个元素会消除整个过程?

Arrays 为什么在bash中取消设置数组的第一个元素会消除整个过程?,arrays,bash,unset,Arrays,Bash,Unset,不久前,我编写了一个脚本,以处理几周、几个月甚至几年的日常数据。我需要做的一件事是删除第一个元素,否则结果中会出现一个重复的条目。那剧本效果很好。快进几个月,我需要制作一个相同的脚本,它在调用某些二进制文件和脚本来处理数据方面有所不同。我复制了脚本并进行了相关更改,保留了日期序列的生成和第一个元素的删除。当我运行这个新脚本时,当为第一个元素调用unset时,整个日期数组都会被取消设置 以下是脚本: #!/bin/sh if [ "$1" = '' ] || [ "$3" = '' ]; the

不久前,我编写了一个脚本,以处理几周、几个月甚至几年的日常数据。我需要做的一件事是删除第一个元素,否则结果中会出现一个重复的条目。那剧本效果很好。快进几个月,我需要制作一个相同的脚本,它在调用某些二进制文件和脚本来处理数据方面有所不同。我复制了脚本并进行了相关更改,保留了日期序列的生成和第一个元素的删除。当我运行这个新脚本时,当为第一个元素调用unset时,整个日期数组都会被取消设置

以下是脚本:

#!/bin/sh

if [ "$1" = '' ] || [ "$3" = '' ]; then
    echo -e "Uso:\t$0 <estacion> <inicio> <fin>"
    echo
    echo -e "\tEl argumento 'estacion' es el identificador de una de las estaciones en"
    echo    "maysculas (e.g. RMA1_FDC). Los otros dos--'inicio' y 'fin'--son fechas de la"
    echo    "forma AAAA-[M]M-[D]D, dondeA corresponde a un digito del año, M para el mes, y D"
    echo    "para el dia. Notese que el mes y el dia solo requieren un digito si el valor"
    echo    "para este campo es menor a diez. No es necesario poner '0' adelante del numero"
    echo    "en este caso."
    echo
    echo    "Este programa genera datos en formato CSV (coma separated values) en la salida"
    echo    "estandar. Si desea guardarlos a un archivo, redirija la salida al mismo. Ej."
    echo
    echo    "$0 RMA1_FDC 2018-7-1 2018-12-10 > registro.csv"
    echo

    exit -1
fi

PRECIPITACION_MODELO=2
PRECIPITACION_ESTACION=5
DIA_A=$2
FECHAS=$(seq $(date +%s -d $2) 86400 $(date +%s -d $3))
>&2 echo "Fechas = "${FECHAS[*]}
unset -v FECHAS[0]
>&2 echo "Fechas = "${FECHAS[*]}

echo "fecha,'delta precipitacion',corrida"

for d in ${FECHAS[@]}; do
    DIA_B=$(date +%Y-%-m-%-d -d @$d)
    >&2 echo "$DIA_A -- $DIA_B"
    ./getstationdata  $1 $DIA_A $DIA_B $PRECIPITACION_ESTACION > estacion 2> /dev/null

    ./getwrfdata  $1 $DIA_A $DIA_B $PRECIPITACION_MODELO A > pronostico 2> /dev/null
    echo -n "$DIA_A,"
    ./delta-precipitacion 2> /dev/null | awk 'ORS=NR%3?" ":"\n"' | awk '{print $2 ",A"}'

    ./getwrfdata  $1 $DIA_A $DIA_B $PRECIPITACION_MODELO B > pronostico 2> /dev/null
    echo -n "$DIA_A,"
    ./delta-precipitacion 2> /dev/null | awk 'ORS=NR%3?" ":"\n"' | awk '{print $2 ",B"}'

    ./getwrfdata  $1 $DIA_A $DIA_B $PRECIPITACION_MODELO C > pronostico 2> /dev/null
    echo -n "$DIA_A,"
    ./delta-precipitacion 2> /dev/null | awk 'ORS=NR%3?" ":"\n"' | awk '{print $2 ",C"}'

    ./getwrfdata  $1 $DIA_A $DIA_B $PRECIPITACION_MODELO D > pronostico 2> /dev/null
    echo -n "$DIA_A,"
    ./delta-precipitacion 2> /dev/null | awk 'ORS=NR%3?" ":"\n"' | awk '{print $2 ",D"}'

    DIA_A=$DIA_B;
    DIA_B=$(date +%Y-%-m-%-d -d @$d)
done

rm -f estacion pronostico

我得到一系列数字,表示第一个“echo”的日期,但简单的“FECHAS=”表示第二个。这件事已经困扰了我一个星期了。有人知道它出了什么问题吗?

这里有一个更简单的方法来重现您的问题:

var="foo bar"
echo "The value is: ${var[*]}"
unset -v 'var[0]'
echo "The value is now: ${var[*]}"
这将产生:

The value is: foo bar
The value is now:
之所以会出现这种情况,是因为变量不是数组,只是bash允许您将正则变量视为数组,在索引0处有一个值:

var="foo bar"
echo "No index = $var"
echo "[0] = ${var[0]}"
echo "[1] = ${var[1]}"
产出:

No index = foo bar
[0] = foo bar
[1] =
如果在上述示例中使用
var=(“foo”“bar”)
创建实际数组,则会得到预期结果:

No index = foo
[0] = foo
[1] = bar
The value is: foo bar
The value is now: bar

FECHAS
不是数组,您可以使用
FECHAS=$(cmd)
创建它,但要获得数组,您需要
FECHAS=($(cmd))
。这就是说,您的shebang行不应该包含
/bin/sh
,因为它首先不支持数组–使用
/bin/bash
/usr/bin/env bash
。什么是
FECHAS
,它应该是一个数组,但看起来像是一个变量Benjamin W,D'OH!谢谢我刚检查了原件,这正是不同之处。请你把它作为回答而不是评论,这样我就可以把它标记为解决方案了?谢谢另一个人的回答完全涵盖了这一点。旁注:本不会告诉你确切的问题,但其他人(如
-1
不是有效的退出状态)。没错,但指出FECHAS的初始化是错误的是我问题的解决方案,也是第一个有用的答案(当我收到你的回复通知时,那篇帖子还没有发布)。初始化它们的正确方法就隐藏在这里,如果不看那篇文章和我的代码一百遍,就很难推断出我弄错了:)在GNU bash 4.3.46版上,变量上的
unset
抛出了预期的正确错误-
bash:unset:var:不是数组变量。4.4.19在我的系统上没有。我要说的是:“噢,GNU!”。无论如何,BASH为什么要这样做,把标量当作单元素矩阵来对待?@JamieRamone你访问标量中的各种索引,所以你才是把标量当作数组来对待的人。Bash尽力解释您的意思。
No index = foo
[0] = foo
[1] = bar
The value is: foo bar
The value is now: bar