2016-05-06 2 views
2

Мне нужно найти массив значений. Они будут представлять идентификаторы сервера и/или виртуального сервера, которые они будут представлять. Поэтому я должен запустить 100 экземпляров приложений на 25 серверах. server 1 runs process 1,26,51,76 server 2 runs process 2,27,52,77 ... server 25 runs process 25,50,75,100 bash создать массив идентификаторов для запуска процессов

Мне нужен способ, чтобы выполнить сценарии как этот

# hostname is in a format like production-01.localdomain 
host_id=`hostname | tr 'A-Za-z-.' ' ' | tr -d '[[:space:]]'` 

# need to create array of server ids in server_ids 

for server_id in server_ids 
do 
    /usr/local/bin/virtual_process $server_id 
done 

, но я не знаю, как создать массив server_ids. Помогите!

+0

Помогает ли это? http://www.thegeekstuff.com/2010/06/bash-array-tutorial/ –

+1

В 'bash' нет команды' foreach', это просто 'for'. – Barmar

+0

Вы правы. Я перепутал языки на второй, я имел в виду для –

ответ

1

здесь ya go. Это решает проблему путем создания пространства отделенной строки вместо массива, который был бы излишним

# hostname is in a format like production-01.localdomain 
server_id=`hostname | tr 'A-Za-z-.' ' ' | tr -d '[[:space:]]' | awk '{print NR}'` 

# need to create array of server ids in server_ids 
server_ids="$server_id $(($server_id+25)) $(($server_id+50)) $(($server_id+75))" 

for server_id in $server_ids 
do 
    /usr/local/bin/virtual_process $server_id 
done 
+1

Кроме того, значение 'host_id', которое, я думаю, должно быть начальным« server_id »? В противном случае он всегда будет начинаться с базы 0. –

+0

ya, это была опечатка. должен был быть server_id – jbrahy

+0

Хотя понятно, что ваш ответ сосредоточен на главном вопросе, он может смущать будущих читателей скопировать _broken_ части кода OP дословно (подстановка команды для извлечения номера из имени хоста, псевдо 'for' loop code). Кроме того, при составлении одной строки аргумента для передачи без кавычек в 'for', в этом случае работает, это хрупкая техника в целом. Я предлагаю добавить комментарий к этому вопросу на вопрос или изменить решение для использования переменной _array_. – mklement0

0

Если вам просто нужна последовательность чисел от 1 до 25, вы можете использовать bash's brace expansion.

for server_id in {1..25} 
do 
    /usr/loca/bin/virtual_process $server_id 
done 
+0

Мне нужно иметь текущий идентификатор сервера + 0, текущий идентификатор сервера + 25, текущий идентификатор сервера + 50 и текущий идентификатор сервера + 75, –

1

Вот идиоматическое решение Bash, который должен работать как есть:

#!/usr/bin/env bash 

# Extract the base server ID by extracting the number from the hostname, 
# eliminating any leading zeros. 
# E.g., 'production-01.localdomain' -> '1' 
baseServerId=$((10#$(tr -dC '[0-9]' <<<"$HOSTNAME"))) 

# Loop 4 times, starting with the base server ID and 
# adding 25 in each subsequent iteration. 
for ((i = 0; i < 4; ++i)); do 
    /usr/local/bin/virtual_process "$((baseServerId + i * 25))" 
done 

Как вы можете видеть,

  • Один tr команды с использованием -C для дополнения достаточно, чтобы извлечь только цифры: -dC '[0-9]' средства: delete (-d) все но (-C) цифры ([0-9]).

    • Так как полученное число может иметь ведущие нули, то они должны быть удалены, чтобы избежать неправильной интерпретации как восьмеричного числа. Оценка команды tr внутри арифметического расширения $((...)) с 10# - желаемое числовое основание - добавлено к выходу tr, делает именно это.
  • Нет необходимости в массиве идентификаторов серверов, когда арифметическая, петля C-стиль будет делать.


Тем не менее, так как список смещений настолько мала, и имеет фиксированные приращения, более лаконичное решение:

for offset in 0 25 50 75; do 
    /usr/local/bin/virtual_process "$((baseServerId + offset))" 
done 

Более алгоритмический подход с использованием brace expansion (который, он должен Следует отметить, что поддерживается только literal аргументы; Bash v4 + требуется из-за использования третьего аргумента для указания шаг значение):

for offset in {0..75..25}; do 
    /usr/local/bin/virtual_process "$((baseServerId + offset))" 
done 
+0

Когда я попробовал это, я получил сообщение об ошибке: «08: слишком большое значение для базы (токен ошибки« 08 »)« есть ли способ получить значение int для строки «08»? –

+1

@ Johnny3653925: Мой плохой - я не думал о ведущих нулях, что вызывает неправильное толкование как _октальное число; см. мое обновление. – mklement0

 Смежные вопросы

  • Нет связанных вопросов^_^