sh - массив Readonly: имя плохой переменной

Мой скрипт запускает программу и проверяет вывод с ожидаемым. Почему это не работает? (Пробуйте ошибку 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
задан 14 November 2017 в 04:33

6 ответов

Как писал steeldriver в комментарии,

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

Итак, как только вы изменили shebang на #!/bin/bash, как comment , вам нужно будет изменить объявления массива:

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
ответ дан 22 May 2018 в 17:49

Как писал steeldriver в комментарии,

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

Итак, как только вы изменили shebang на #!/bin/bash, как comment , вам нужно будет изменить объявления массива:

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
ответ дан 18 July 2018 в 05:42

Как писал steeldriver в комментарии,

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

Итак, как только вы изменили shebang на #!/bin/bash, как comment , вам нужно будет изменить объявления массива:

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
ответ дан 24 July 2018 в 18:24

Начиная с вашего скрипта с #!/bin/sh, вы сообщаете системе использовать только интерпретатор интерпретатора dash (только для POSIX). См. [F3]. dash не поддерживает массивы оболочки.

Если вы измените первую строку на #!/bin/bash, вы получите все функции bash, включая массивы. См. [F7].

1
ответ дан 22 May 2018 в 17:49
  • 1
    это правильный плюс, поскольку вышеперечисленный steeldriver имеет readonly в конце. поэтому: FILENAMES [0] = "0.file" FILENAMES [1] = & Quot; 1.file & Quot; Только зарегистрированные FILENAMES – Kees Beets 5 October 2017 в 21:57

Начиная с вашего скрипта с #!/bin/sh, вы сообщаете системе использовать только интерпретатор интерпретатора dash (только для POSIX). См. [F3]. dash не поддерживает массивы оболочки.

Если вы измените первую строку на #!/bin/bash, вы получите все функции bash, включая массивы. См. [F7].

1
ответ дан 18 July 2018 в 05:42

Начиная с вашего скрипта с #!/bin/sh, вы сообщаете системе использовать только интерпретатор интерпретатора dash (только для POSIX). См. [F3]. dash не поддерживает массивы оболочки.

Если вы измените первую строку на #!/bin/bash, вы получите все функции bash, включая массивы. См. [F7].

1
ответ дан 24 July 2018 в 18:24
  • 1
    это правильный плюс, поскольку вышеперечисленный steeldriver имеет readonly в конце. поэтому: FILENAMES [0] = "0.file" FILENAMES [1] = & Quot; 1.file & Quot; Только зарегистрированные FILENAMES – Kees Beets 5 October 2017 в 21:57

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

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