WedX - журнал о программировании и компьютерных науках

Изменение поведения declare/local с bash 4.2 на 4.3

Недавно я обновил свою систему и получил новую версию bash. С тех пор я столкнулся с некоторым неприятным поведением моих скриптов bash, которое мне, наконец, удалось отследить до нового поведения команд bash declare / local.

Рассмотрим следующий минимальный рабочий пример:

#!/bin/bash

function printarray1 () {
  local -a arr=("${!1}")
  echo "${arr[@]}" # printing the complete array
  echo "${arr[9]}" # just to check if it is really recognized as an integer indexed array
}

function printarray2 () {
  local arr=("${!1}")
  echo "${arr[@]}" # printing the complete array
  echo "${arr[9]}" # just to check if it is really recognized as an integer indexed array
}

arr=("01" "02" "03" "04" "05" "06" "07" "08" "09" "10")
echo "Declaration as indexed array:"
printarray1 arr[@]
echo "Undefined declaration:"
printarray2 arr[@]

В GNU bash версии 4.2.25(1)-выпуск (x86_64-pc-linux-gnu) это приводит к

Declaration as indexed array:
01 02 03 04 05 06 07 08 09 10
10
Undefined declaration:
01 02 03 04 05 06 07 08 09 10
10

в то время как более новая версия GNU bash, версия 4.3.11(1)-выпуск (x86_64-pc-linux-gnu) возвращает

Declaration as indexed array:

Undefined declaration:
01 02 03 04 05 06 07 08 09 10
10

Обратите внимание, что поведение такое же, когда я использую «объявить» вместо «локальный».

Мне не удалось найти ничего об изменении параметров declare в Bash 4.3. Справка (help declare) одинакова в обеих версиях для всей соответствующей информации. Я даже наткнулся на утверждение, что «все переменные могут использоваться как массивы без явного определения». (см. Почему объявляют -f и объявляют - требуется в сценариях bash?).

Кто-нибудь может объяснить такое поведение? Это новая функция? Или просто баг? Ограничена ли передача массивов функциям? Для меня это довольно страшно, когда поведение bash внезапно меняется от версии к версии.

27.10.2015

  • Проблема заключается в конфликте имени переменной. Используйте другую глобальную переменную, и проблема исчезнет. 27.10.2015
  • С другим именем переменной это действительно работает. Но это на самом деле не объясняет различий в поведении Bash 4.2 и 4.3, а также declare -a и declare. И я предположил, что смысл ключевого слова local заключался в том, чтобы скрыть переменные из локальной области видимости. 27.10.2015
  • Ага. При беглом просмотре примечаний я не увидел ничего, что могло бы объяснить это, и я ожидал, что в новой версии он полностью сломается, а не только частично. Я чувствую, что видел вопрос об этом, прежде чем мне придется немного поискать его. 27.10.2015
  • @EtanReisner Вы, вероятно, помните мой вопрос несколько месяцев назад, хотя это было сделать с ошибкой в ​​bash 3.1. 27.10.2015
  • @ 123 Почти наверняка правильно. Спасибо. Однако сейчас нет времени посмотреть, применимо ли что-то подобное и здесь. 27.10.2015
  • Просматривая журналы изменений, я не вижу ничего, что предполагало бы такое поведение, поэтому я думаю, что это, вероятно, ошибка, аналогичная той, что была в моем вопросе в моем комментарии. 27.10.2015
  • Звучит разумно, хотя было бы странно, если бы такое поведение было в 3.1, затем исправлено в 3.2 и, наконец, вновь введено в 3.3. Хотя в вашем вопросе опция -a не задействована. 28.10.2015
  • Только что вернулся, чтобы снова посмотреть на это, и я все еще думаю, что это снова должна быть та же ошибка bash. Я хотел бы поговорить об этом с людьми из bash. (Я только что воспроизвел это с помощью bash 4.3.42(1)-release тоже.) В журнале изменений bash для 4.3-beta есть запись, которая может иметь смутное отношение (1.d). 15.01.2016
  • Список рассылки bash показал, что local -a arr=("${!1}") расширится до local -a arr; arr=( "${!1}" ), а затем до local -a arr; arr=( "${arr[@]}" ). т.е. локальная переменная с тем же именем сначала определяется без значения и, следовательно, затеняет глобальную переменную arr. Объясняет поведение, но не исключительный случай с переключателем -a. 20.02.2016

Новые материалы

Как создать диаграмму градиентной кисти с помощью D3.js
Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

Объяснение документов 02: BERT
BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


Для любых предложений по сайту: [email protected]