4

Я пишу / все еще мозговой штурм / сценарий оболочки bash . Целью которого является; помочь пользователю:

  • Интерфейс с различными инструментами CLI.
  • Выполните различные административные задачи.

Это может в конечном итоге превратиться в нечто вроде персонализированной структуры.


Особое требование, чтобы оно имело:

  • Он должен быть в состоянии определить IP-адрес шлюза / маршрутизатора в текущей локальной сети.
  • Я придумал route -n |awk '/UG/{print $2}'; повторить соответствующий IP к stdout.

Должен ли я использовать этот вход как function(){ } , он выводится как $variable , или как??


Вот несколько простых идей, которые у меня были:

  1. #function#
    gw() { route -n |awk '/UG/{print $2}'; }
  2. #variable#
    gw="$( route -n |awk '/UG/{print $2}'; )"
  3. #function#
    gw() { route -n |awk '/UG/{print $2}'; }
    
    #variable#
    gw="$( route -n |awk '/UG/{print $2}'; )"
  4. #function#
    gw() { route -n |awk '/UG/{print $2}'; }
    
    #variable#
    gw="$(gw)"

1 ответ1

2

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

Вот несколько общих комментариев:

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

  • Для обработки вывода из функции, я считаю, что использование stdout является наиболее универсальным методом, и он поддается модульному / упаковочному подходу построения функций.

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

Если у вас есть функция, которая присваивает себя переменной внутри той же функции; например

`testFx() { export routeInfo="$(route)"; }`

Если присвоение переменной routeInfo функцией 'testFx' находится в той же области, что и вызывающая сторона - другими словами, если функция объявлена в текущей оболочке и вызвана из текущей оболочки, результирующее присваивание переменной routeInfo будет доступно из этого ракушка. Если функция используется в исполняемом скрипте, результат не будет доступен оболочке, вызвавшей скрипт, хотя функция будет доступна.

Это немного упрощает, но я думаю, что это хорошо проясняет проблему. Объекты в области видимости родительского объекта доступны для дочерней оболочки / процесса, но не наоборот. Трудно передать вещи «обратно вверх по линии» (в bash).

Это различие проявляется в различном поведении, которое наблюдается при поиске файла сценария и выполнении файла сценария.

Выполненный скрипт запускается в дочерней / дочерней оболочке; исходный файл добавляется в локальную среду в текущем контексте; не в дочерней / подчиненной оболочке.

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

Затем вызовите функцию и попытайтесь отобразить переменную, содержащую значение, echo $routeInfo . Это будет работать, как ожидалось.

Очистить эту переменную с помощью unset routeInfo

Затем создайте простой скрипт следующим образом:

vi ~/test.sh

с содержанием:

#!/bin/bash
testFx

Сохраните, закройте и добавьте разрешения на выполнение chmod +x ~/test.sh

Затем запустите скрипт ~/test.sh из оболочки, в которой определена эта функция.

После запуска скрипта откройте переменную, которая должна содержать значение: echo $routeInfo , и вы увидите, что она пуста - при условии, что вы сделали неустановленный вызов выше; потому что экспорт не смог подняться к родительской оболочке / процессу.

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

Вот несколько примеров «захвата» выходных значений из функций bash

rslt=$(testFx)
Если вы можете ожидать нескольких результатов, вы можете сохранить результаты в массиве:
rslt=($(testFx)) с ${#rslt[@]} содержащим количество записей (N), и вы можете получить доступ к элементам либо путем прямой индексации:
${rslt[$a]} с a = 0 до N-1
или через цикл:
for i in ${rslt[@]}; do echo "$i"; done

Надеюсь, это решило большую часть вашего вопроса. Я добавляю несколько функций сбора сетевых данных на моем локальном компьютере. Если вы ищете какую-либо конкретную информацию, дайте мне знать, у меня, вероятно, есть функция для этого.

getExternalIP () {
    lynx -dump -hiddenlinks=ignore -nolist http://checkip.dyndns.org:8245/ | grep "Current IP Address" | cut -d":" -f2 | cut -d" " -f2
}

getLanIP () {
    ip addr show | grep -E -v '127\.0' | grep -Eo '^.*brd' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
}

getDefGW_IP () { 
    route -n | awk '/UG/ {print $2}'; 
}

getDefGW_Host () { 
    route  | awk '/default/ {print $2}'; 
}    

getDefGW_Host_and_IP () { 
    echo "Def. GW hostname / IP Address: $(getDefGW_Host) / $(getDefGW_IP)";
}

Вот полезная строка регулярного выражения для использования при работе с IP-адресами:

iprgx='(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'

Пример использования этого - функция для вывода всех IP-адресов в вашей локальной сети, с которых вы видели пакеты ARP:

getARPTable_IPs() {
    arp -na | grep -Eo "$iprgx";
}

Сохраните результаты в массиве:

arpIPs=($(getARPTable_IPs))

Наконец, для современного дистрибутива Linux, здесь приведены команды и местоположения файловой системы, которые я часто использую для получения информации о сети / статуса. Старые команды, такие как netstat и ifconfig, устарели и по уважительным причинам.

  1. IP
  2. сс
  3. В /sys /class /net будет каталог для каждого сетевого адаптера в вашей системе, заполненный файлами, содержащими информацию о сети.
    а. Многие утилиты командной строки просто используют этот вывод и переформатируют его.
    б. /proc /net содержит много информации.
    с. Например, команда arp -na может быть полностью скопирована командой cat /proc/net/arp
  4. Iptables

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .