sh - Массив только для чтения: плохое имя переменной

Мой сценарий запускает программу и проверяет вывод с ожидаемым. Почему это не работает?? (Prob, который путает n00b, я делаю),

Консоль:

dan9er@A-Computer:~/Projects/Project$ ./Script.sh
./Script.sh: 13: readonly: FILENAMES[0]: bad variable name

Сценарий:

#!/bin/sh

# Copyright (c) 2017 Unattended Systems
# Some names & strings have been changed for confidentiality

#  ####### ### #       #######  #####
#  #        #  #       #       #
#  #####    #  #       #####    #####
#  #        #  #       #             #
#  #       ### ####### #######  #####

readonly FILENAMES[0]="0.file"
readonly FILENAMES[1]="1.file"
readonly FILENAMES[2]="2.file"
readonly FILENAMES[3]="3.file"
readonly FILENAMES[4]="4.file"
readonly FILENAMES[5]="5.file"
readonly FILENAMES[6]="6.file"
readonly FILENAMES[7]="7.file"
readonly FILENAMES[8]="8.file"
readonly FILENAMES[9]="9.file"
readonly FILENAMES[10]="10.file"
readonly FILENAMES[11]="11.file"
readonly FILENAMES[12]="12.file"
readonly FILENAMES[13]="13.file"
readonly FILENAMES[14]="14.file"
readonly FILENAMES[15]="15.file"
readonly FILENAMES[16]="16.file"
readonly FILENAMES[17]="17.file"
readonly FILENAMES[18]="18.file"
readonly FILENAMES[19]="19.file"
readonly FILENAMES[20]="20.file"
readonly FILENAMES[21]="21.file"

#  ####### #     # ######  #######  #####  ####### ####### ######
#  #        #   #  #     # #       #     #    #    #       #     #
#  #####      #    ######  #####   #          #    #####   #     #
#  #        #   #  #       #       #     #    #    #       #     #
#  ####### #     # #       #######  #####     #    ####### ######
#
#   #####  #     # ####### ######  #     # #######  #####
#  #     # #     #    #    #     # #     #    #    #
#  #     # #     #    #    ######  #     #    #     #####
#  #     # #     #    #    #       #     #    #          #
#   #####   #####     #    #        #####     #     #####

readonly EXPECTEDOUT[0]=$"Hello World!"
readonly EXPECTEDOUT[1]="1"
readonly EXPECTEDOUT[2]="2"
readonly EXPECTEDOUT[3]="3"
readonly EXPECTEDOUT[4]="4"
readonly EXPECTEDOUT[5]="5"
readonly EXPECTEDOUT[6]="6"
readonly EXPECTEDOUT[7]="7"
readonly EXPECTEDOUT[8]="8"
readonly EXPECTEDOUT[9]="9"
readonly EXPECTEDOUT[10]="10"
readonly EXPECTEDOUT[11]="11"
readonly EXPECTEDOUT[12]="12"
readonly EXPECTEDOUT[13]="13"
readonly EXPECTEDOUT[14]="14"
readonly EXPECTEDOUT[15]="15"
readonly EXPECTEDOUT[16]="16"
readonly EXPECTEDOUT[17]="17"
readonly EXPECTEDOUT[18]="18"
readonly EXPECTEDOUT[19]="19"
readonly EXPECTEDOUT[20]="20"
readonly EXPECTEDOUT[21]="21"

#  #        #####   #####  ###  #####
#  #       #     # #        #  #     #
#  #       #     # #  ####  #  #
#  #       #     # #     #  #  #     #
#  #######  #####   #####  ###  #####

for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
do
    echo "Testing on file ${FILENAMES[$i]}"

    # Run program on file
    program ${FILENAMES[$i]} /tmp/tmp_out

    # If program's output CONTAINS the expected output for that file...
    if grep -q ${EXPECTEDOUT[$i]} /tmp/tmp_out.txt; then
        # ...record that a pass!
        echo -e "String \"${EXPECTEDOUT[$i]}\" found. Pass!"
        RESULTS[$i]=1
    else
        # ..otherwise, epic fail my dude
        echo -e "String \"${EXPECTEDOUT[$i]}\" not found. FAIL!"
        RESULTS[$i]=0
    fi
done

# Make a final list of results
PASSEDTESTS=0
for j in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
do
    if [[ ${RESULTS[$j]} == 1 ]]; then
        echo "${FILENAMES[$j]} passed"
        PASSEDTESTS=PASSEDTESTS+1
    else
        echo "${FILENAMES[$j]} failed"
    fi
done
echo "$PASSEDTESTS/22 files passed"

Имена файлов действительно имеют символы нижнего подчеркивания в них.

0
задан 13 November 2017 в 17:33

2 ответа

Поскольку steeldriver записал в комментарии,

bash не делает поддержки a readonly объявление для отдельных элементов массива.

Таким образом, после того как Вы изменили хижину на #!/bin/bash, как waltinator предложенный, необходимо будет изменить объявления массива:

FILENAMES[0]="0.file"
FILENAMES[1]="1.file"
...
readonly FILENAMES

Или можно сократить их при помощи присваивания массива (=()) и расширение оболочки ({}) синтаксис:

readonly FILENAMES=(
    {0..21}.file
    )

...

readonly EXPECTEDOUT=(
    $"Hello World!"
    {1..21}
    )

Можно также сократить объявление цикла:

for i in {0..21}

...

for j in {0..21}
1
ответ дан 2 November 2019 в 04:05

Путем начала сценария с #!/bin/sh, Вы говорите системе использовать dash (только функции POSIX) интерпретатор оболочки. См. man sh;man dash. dash не поддерживает массивы оболочки.

при изменении первой строки на #!/bin/bash Вы доберетесь весь эти bash функции, включая массивы. См. man bash.

1
ответ дан 2 November 2019 в 04:05

Другие вопросы по тегам:

Похожие вопросы: