Как настроить сервер OpenSSH для подключения к консоли изолированного компьютера через последовательный порт?

What happens for example is if output[2] and [4] are empty, output[6] will shift up to the line corresponding to output [2].

В этом случае у вас действительно нет пустых значений вместо 2 и 4, просто у вас меньше значений, чем вы ожидаете.

Рассмотрим назначения массивов:

array1=(a b c d)
array2=(A D)

Первый устанавливает array1[0]в a, array1[1]в bи т. д. Второй устанавливает array2[0]в Aи array2[1]в D. Невозможно узнать, должны ли быть пустые значения между Aи D. Они должны быть явно указаны в задании :

.

array2=(A "" "" D)

Возможно, вы заполняете массив outputкаким-то другим способом, но поскольку вы не показываете, как это делается, нет возможности прокомментировать это. Вероятно, у вас есть случай, аналогичный приведенному выше :: «пустые» значения вообще не рассматриваются как значения тем, что заполняет массив output.

Если вы присваиваете значение массиву из расширения и полагаетесь на разбиение слов -, вы не можете избежать этого. (Даже если IFSсодержит только новую строку, он будет складывать последовательные пустые строки новой строки в одну, удаляя пустые строки ). Если вы используете mapfile, то пустые строки должны отображаться как элементы массива по умолчанию.


В любом случае ваш цикл для обнуления пустых элементов массива не работает, потому что вы вообще не присваиваете значение массиву внутри цикла (), и даже если вы это сделали, тело цикла выполняется в подоболочка (, отмеченная скобками (...)), так что никакие присваивания в любом случае не будут выполняться вне тела цикла.

Вы не можете использовать for x in "${output[@]}"для полезного изменения элементов массива, так как xполучает только копию значений массива, его изменение не изменяет оригиналы. Вам нужно будет перебрать индексы массива, чтобы иметь возможность указывать на массив:

somearray=(1 "" "" 4)
for i in "${!somearray[@]}"; do
    if [[ -z "${somearray[$i]}" ]]; then
        somearray[$i]=0;
    fi;
done
echo "${somearray[@]}"

печатает 1 0 0 4.


В добавленном примере кода присваивание output+=( $(ssh $h du -sh $path) )не добавит пустых элементов. Отсутствующие пути будут просто исключены из массива. Учтите, что сначала du $pathничего не печатает, если путь не существует. (Помимо ошибки,но это идет в stderr и не фиксируется подстановкой команд. )Кроме того, даже если была напечатана пустая строка (или пробелы/табуляции ), разделение слов удаляет последовательные пробелы.

Попробуйте, например. array=( $( printf "foo\n\nbar\n" ) ), он создает массив из двух элементов.

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

Вы можете заключить подстановку команды("$(ssh... du)")в кавычки, чтобы убедиться, что вы получаете только одну строку, но вы, вероятно, захотите отделить размер от имени пути.

Попробуйте сделать что-то подобное, чтобы собрать пути и их размеры в один массив:

for host in "${hosts[@]}"; do
    for path in "${paths[@]}"; do
        output="$(ssh "$host" du -sh "$path")"
        size="${output%%$'\t'*}"           # needs Bash/ksh/zsh
        size="${size:-0}"
        sizes+=( "$size" "$host:$path"  )
    done
done

Теперь каждый четный элемент массива содержит размер, а каждый нечетный — соответствующее имя хоста и путь, что немного похоже на результат разделения вывода du. Два расширения параметров outputи sizeудалите все после табуляции, а затем замените размер на ноль, если он пуст.

В качестве альтернативы можно построить ассоциативный массив , индексированный по хосту+пути:

declare -A array
...
    array["$host:$path"]=$size
2
04.08.2020, 18:15
0 ответов

Теги

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