Как выполнить итерацию через массив чисел в shell-скрипте?

Я поковырялся в /sys и приблизился к ответу.

# cd /sys/block/md0/md
# cat component_size
2147479552

Это согласуется с тем, что мы видели раньше. Но это:

# grep . dev-sd*/size
dev-sdc/size:2147482623
dev-sdd/size:2147482623
dev-sde/size:2147482623
dev-sdf/size:2930265560
dev-sdg/size:2147482623
dev-sdh/size:2147482623
dev-sdi/size:2147482623
dev-sdj/size:2147482623
dev-sdk/size:2147482623
dev-sdl/size:2147483648
dev-sdm/size:2147482623
dev-sdn/size:2147482623
dev-sdo/size:2147482623
dev-sdp/size:2147482623
dev-sdq/size:2147482623
dev-sdr/size:2147482623
dev-sds/size:2147482623
dev-sdt/size:2147482623
dev-sdu/size:2147482623
dev-sdv/size:2147482623
dev-sdw/size:2930265560

похоже, объясняет, почему RAID видит неправильный размер: Большинство дисков отображаются как 2 ТБ, а 2 диска, которые были заменены, отображаются как 3 ТБ. Все диски одной модели, так что давайте посмотрим, сможем ли мы изменить воспринимаемый размер:

# parallel echo 2930265560 \> ::: dev-sd*/size
# grep . dev-sd*/size
dev-sdc/size:2930265560
dev-sdd/size:2930265560
dev-sde/size:2930265560
dev-sdf/size:2930265560
dev-sdg/size:2930265560
dev-sdh/size:2930265560
dev-sdi/size:2930265560
dev-sdj/size:2930265560
dev-sdk/size:2930265560
dev-sdl/size:2930265560
dev-sdm/size:2930265560
dev-sdn/size:2930265560
dev-sdo/size:2930265560
dev-sdp/size:2930265560
dev-sdq/size:2930265560
dev-sdr/size:2930265560
dev-sds/size:2930265560
dev-sdt/size:2930265560
dev-sdu/size:2930265560
dev-sdv/size:2930265560
dev-sdw/size:2930265560

Вуаля. Component_size все еще мал, хотя:

# cat component_size
2147479552

Возможно, его можно изменить с помощью mdadm:

# mdadm --grow /dev/md0 --size=max

К сожалению, это блокирует mdadm и последующий доступ к /dev/md0 блокируется. Как и доступ к component_size:

# cat component_size   # This blocks

Хреново. Но хорошо то, что в syslog написано:

Apr 27 20:45:50 server kernel: [124731.725019] md0: detected capacity change from 39582343102464 to 54010589478912

Файловая система на /dev/md0 все еще работает.

После перезагрузки мне пришлось снова выполнить 'mdadm --grow /dev/md0 --size=max'. Затем дождаться завершения resync. И снова доступ к /dev/md0 был заблокирован. Поэтому еще одна перезагрузка, затем xfs_growfs /dev/md0, после чего изменение размера было завершено.

1
13.09.2018, 18:04
4 ответа

Не заключайте в двойные кавычки ссылку на msgNumbers, а msgNumbers не является массивом, поэтому индексирование бессмысленно.

0
27.01.2020, 23:31

Насколько я вижу, в вашем коде нет массива. Переменная msgNumbersпредставляет собой строку, содержащую вывод вашей команды cut.

Для повторения вывода cutиспользуйте

#!/bin/bash

mailx -H | grep '^ [UN]' | cut -c 4-5 |
while read msg; do
    print 'msg = %s\s' "$msg"
done

Это отправляет вывод cutв цикл while, следующий за ним, через канал(|). Цикл whileбудет повторяться с msg, установленным для каждой отдельной строки вывода из cut.

cutполучает данные непосредственно из команды grep, что устраняет необходимость сохранения данных в промежуточном файле или переменной.

Я удалил команду echo $msg|mailx;, потому что она не имела для меня особого смысла (утилите mailxнужен адрес для отправки данных на ).

grep+ cutтакже можно заменить одним вызовом awk, где мы позволяем awkвыполнять работу обоих инструментов и выводить второй столбец с разделителями-пробелами -, когда регулярное выражение соответствует:

#!/bin/bash

mailx -H | awk '/^ [UN]/ { print $2 }' |
while read msg; do
    print 'msg = %s\s' "$msg"
done

Я не буду дальше комментировать использование mailx, так как это не -стандартная утилита, которая реализована немного по-разному в системах Unix (моя версия не имеет опции -H, например ).


Строка#!-кажется мне приемлемой, если вы хотите, чтобы скрипт выполнялся с помощью bashи если исполняемый файл bashрасположен по этому пути (, который обычно находится в системах Linux, например, но проверьте command -v bashв вашей системе, чтобы убедиться ). Код, который я разместил выше, совместим с /bin/sh, поэтому bashне является действительно необходимым для его запуска (он будет работать в любойsh-подобной оболочке ).

Просто убедитесь, что скрипт является исполняемым и что вы запускаете его без явного указания интерпретатора.

2
27.01.2020, 23:31

Используйте ()для сохранения значения в виде массива.

msgNumbers=(`cut -c 4-5 ListOfMessages.txt`)
echo "${msgNumbers[@]}"
for msg in "${msgNumbers[@]}";
do
echo $msg;
done
0
27.01.2020, 23:31

Проблема решена. Проблема заключалась в том, что msgNumbers не был индексированным массивом. Поэтому я изменил for msg in "${msgNumbers[@]}";на for msg in ${msgNumbers};. Теперь все работает. Остальной код такой же, как в моем вопросе.

0
27.01.2020, 23:31

Теги

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