Как вы уже поняли, выражение без кавычек , такое как 1..18
, прекрасно работает : оно использует оператор PowerShell оператор диапазона (..
) для создания массива смежных целых чисел от 1
до 18
; то есть это эквивалент следующего массива литерал :
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18
В отличие от этого, "1..18"
является (расширяемой) строкой , содержимое которой печатается как есть (в данном случае литерал 1..18
, поскольку строка не содержит ссылок на переменные). ни подвыражения).
Важно : Хотя технически работает с Invoke-Expression
для оценки строки в качестве оператора PowerShell (например, Invoke-Expression "1..18"
), этот подход следует избегать : Invoke-Expression
является редко подходящим инструментом и представляет угроза безопасности , особенно при несанкционированном вводе пользователем - см. сообщение в блоге команды PowerShell под названием «Вызывание-выражение считается вредным» .
Ваша задача заключается в создании такого диапазона на основе пользовательского ввода , который по умолчанию представляет собой строку , возвращаемую Read-Host
.
Оператор диапазона способен динамически преобразовывать любой операнд (конечная точка диапазона) в целое число, и с радостью принимает выражения в качестве конечных точек диапазона
1..(Read-Host 'Enter the upper bound')
Если вы введете 3
(который, как указано, возвращается как строка ), PowerShell динамически преобразует эту строку в ее целочисленный эквивалент и создает массив 1..3
, вывод которого по умолчанию выглядит следующим образом :
1
2
3
Тем не менее, в для того, чтобы (а) предоставить удобный для пользователя запрос о том, что (б) применяет предопределенный диапазон входных данных (чисел), требуется дополнительная работа .
Таким образом:
Убедитесь, что вводимые пользователем данные могут быть преобразованы в (a) число , которое (b) попадает в ожидаемый диапазон; если нет, повторите запрос.
После получения правильного ввода используйте оператор диапазона PowerShell (..
) для построения массива индексов, как вам нужно.
# Define the implied lower bound and the maximum upper bound.
$lowerBound = 1
$maxUpperBound = 18
# Prompt the user for the upper bound of the range, with validation,
# until a valid value is entered.
do {
$userInput = Read-Host -Prompt "How many servers are being tested?"
if (
($upperBound = $userInput -as [int]) -and
($upperBound -ge $lowerBound -and $upperBound -le $maxUpperBound)
) {
break # valid value entered, exit loop.
} else {
# Invalid input: Warn, and prompt again.
Write-Warning "'$userInput' is either not a number or is outside the expected range of [$lowerBound,$maxUpperBound]."
}
} while ($true)
# Create the array of indices based on user input.
1..$upperBound