Я попытался создать сценарий bash, чтобы показать все доступные локальные IP-адреса. Поскольку обычный параметр ping не может работать быстрее 1 секунды на IP-адрес, а fping показывает слишком много вывода при выполнении в цикле for, я попытался сделать это следующим образом:
read -p "Enter Gateway IP Address: " gateway
for ip in $(seq 1 254);
allips = $allips ${gateway::-1} $ip
done
fping -c1 -t500 -a $allips > /dev/null
Но каждый раз, когда я пытаюсь запустить маленький скрипт, он показывает, что
local.sh: line 2: : command not found
local.sh: line 4: syntax error near unexpected token `allips'
local.sh: line 4: ` allips = $allips ${gateway::-1} $ip'
В вашем скрипте есть ряд синтаксических ошибок; Я пройдусь по ним в конце. Но сначала кажется, что есть более простой способ сканировать подсеть / 24: fping
с -g
(генератор) вариант. У меня нет fping
установлен для тестирования, но из документация, это должно работать:
#!/bin/bash
read -p "Enter Gateway IP Address: " gateway
fping -c1 -t500 -a -g "${gateway%.*}.0/24" > /dev/null
В ${gateway%.*}
часть берет введенный IP-адрес шлюза и обрезает, начиная с последнего "." (т.е. последний октет). Итак, если шлюз - «192.168.0.254», это «192.168.0». Затем сценарий добавляет к нему «.0 / 24», чтобы получить «192.168.0.0/24» в качестве строки подсети.
Проблемы в исходном скрипте:
Начните свои сценарии с соответствующей строки shebang. Обычно это будет #!/bin/bash
или #!/usr/bin/env bash
. Вы также увидите #!/bin/sh
, но это может вызвать проблемы, если вы используете в своем скрипте какие-либо расширения синтаксиса bash. Если вы не знаете тонкостей синтаксиса bash vs plain sh, придерживайтесь bash shebang.
Ваш for
в заявлении отсутствует do
. Так должно быть for ip in $(seq 1 254); do
.
bash v3 не допускает отрицательных строковых индексов (например, ${gateway::-1}
). Если у вас версия bash 4, это сработает; если у вас v3, вам нужно вычесть единицу из длины строки: ${gateway::${#gateway}-1}
. Или вы можете использовать оператор обрезки от конца, %
, как я сделал в моем коде выше. Если вы используете ${gateway%.*}
, это удалит последний "." а также номер, поэтому вам нужно добавить его обратно. Другое преимущество заключается в том, что это также будет работать, если последний октет состоит более чем из одной цифры (например, некоторые люди по какой-то причине ставят свои маршрутизаторы на 0,254).
Вы должны почти всегда заключать ссылки на переменные в двойные кавычки, чтобы избежать различных форм неправильного анализа пробелов, подстановочных знаков и т. Д. В этом случае это, вероятно, безопасно, но я бы все равно этого избегал. Но в вашем скрипте вы рассчитываете на разделение слов, чтобы каждый адрес передавался как отдельный аргумент в fping
. Лучший способ сделать это в сценарии оболочки - использовать массив, а не простую переменную, причем каждый аргумент является отдельным элементом массива. Синтаксис для этого немного запутан, но основные операции следующие:
args=(arg1 arg2 "arg with spaces") # The parentheses tell bash this is an array
for x in list of things; do
args+=(additionalarg) # Add elements to array. Both + and () are REQUIRED
done
somecommand "${args[@]}" # Yes, all those parentheses, brackets, etc are needed
Вы не можете использовать пробелы в назначении (если вы не заключаете их в кавычки или экранируете, и в этом случае они являются частью присвоенной строки). Когда вы используете var = something
, оболочка рассматривает это как выполнение команды var
, с участием =
и something
как аргументы. Итак, ваше задание должно выглядеть примерно так:
allips="$allips ${gateway::-1}$ip"
... за исключением того, что, как я сказал выше, вы должны использовать массив. Поэтому установите его на пустой перед циклом (allips=()
), а затем используйте:
allips+=("${gateway%.*}.$ip")
А затем после цикла используйте его так:
fping -c1 -t500 -a "${allips[@]}" > /dev/null