Gateway / Detecção de Roteador com Bash: Funções e Variáveis

4

Estou esboçando / ainda debatendo / um script de shell bash . O objetivo do que é para; ajude o usuário a:

  • Interface com várias ferramentas CLI .
  • Realize várias tarefas administrativas.

Pode, eventualmente, evoluir para um quadro personalizado.

Um requisito específico que tem:

  • Ele deve ser capaz de detectar o endereço IP do gateway / roteador no LAN atual .
  • Eu criei route -n |awk '/UG/{print $2}'; para echo o IP correspondente para < strong> stdout .

Devo usar essa entrada como function(){ } , é saída como $variable ou ambos ??

Aqui estão algumas ideias simples que eu tive:

  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)"
por tjt263 05.06.2016 / 20:07

1 resposta

2

Respondi completamente à sua pergunta, mas espero que seja útil. Eu toquei em algumas coisas gerais e, em seguida, especificidades no gateway padrão e, finalmente, alguns outros exemplos.

Aqui estão alguns comentários gerais:

  • Eu sugiro que você faça essas chamadas em funções que, entre outras coisas, permitirão que você construa suas funções de modo que funções de nível mais alto possam ser simplesmente invólucros em torno de uma ou mais funções de nível inferior.

  • Para manipular a saída de uma função, descubro que usar stdout é o método mais versátil e se presta à abordagem modular / wrapper das funções de construção.

Se você atribuir e exportar variáveis de dentro de uma função, problemas de escopo causarão problemas.

Se você tem uma função que se atribui a uma variável dentro da mesma função; por exemplo,

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

Se a atribuição de variável para routeInfo por 'testFx' estiver no mesmo escopo do responsável pela chamada - em outras palavras, se a função for declarada no shell atual e for chamada a partir do shell atual, a atribuição resultante à variável routeInfo será acessível a partir desse shell. Se a função for usada em um script executado, o resultado não estará acessível ao shell que chamou o script, embora a função esteja acessível.

Isso é um pouco simplista, mas acho que isso esclarece bem a questão do escopo. Objetos no escopo de um pai são acessíveis a um shell / processo filho, mas não vice-versa. É difícil passar as coisas "de volta" para a linha (no bash).

Essa diferença é exposta no comportamento diferente visto quando se procura um arquivo de script versus a execução de um arquivo de script.

O script executado é executado em um shell sub / child; o arquivo originado é adicionado ao ambiente local no contexto atual; não em uma shell filho / sub.

Você pode testar o que estou dizendo adicionando essa função simples ao seu shell - simplesmente cole-a (ou adicione a .bashrc e recarregue o shell, etc.)

Em seguida, chame a função e tente ecoar a variável que contém o valor, echo $routeInfo . Isso funcionará como esperado.

Limpe essa variável com unset routeInfo

Em seguida, crie um script simples da seguinte forma:

vi ~/test.sh

com conteúdo:

#!/bin/bash
testFx

Salve, feche e adicione permissões de execução chmod +x ~/test.sh

Em seguida, execute o script ~/test.sh de um shell que tenha essa função definida nele.

Depois de executar o script, faça eco da variável que deve conter o valor: echo $routeInfo e você verá que está vazio - supondo que você fez a chamada não definida acima; porque a exportação não conseguiu ascender ao shell / processo pai.

Devido a esse problema de escopo e à falta de um valor tradicional de 'retorno' de uma função bash, a maneira como normalmente vejo o valor de 'resultado' de uma função bash usada é diretamente; deixando a saída para stdout ou capturando-a em uma variável. Para ambos os casos, a função em si é escrita da mesma maneira, apenas a maneira como ela é chamada é alterada.

Aqui estão alguns exemplos de 'pegar' valores de saída de funções bash

rslt=$(testFx)
Se você puder esperar vários resultados, poderá armazenar os resultados em uma matriz:
rslt=($(testFx)) com ${#rslt[@]} contendo o número de entradas (N), e você pode acessar os elementos por indexação direta:
${rslt[$a]} com a = 0 a N-1
ou através de um loop: for i in ${rslt[@]}; do echo "$i"; done

Espero que isso tenha respondido boa parte de sua pergunta. Estou jogando algumas funções de coleta de dados de rede que tenho em minha máquina local. Se você estiver procurando por qualquer outra informação específica, deixe-me saber, eu provavelmente tenho uma função para isso.

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)";
}

Aqui está uma string regex útil para usar ao trabalhar com endereços 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]?)'

Exemplo usando isso - uma função para mostrar todos os endereços IP em sua LAN dos quais você viu os pacotes ARP:

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

Armazene os resultados em uma matriz:

arpIPs=($(getARPTable_IPs))
Por último, para uma distro linux moderna, aqui estão os comandos e os locais do sistema de arquivos que eu uso com frequência para obter informações / status da rede. Comandos mais antigos, como netstat e ifconfig, estão obsoletos e por boas razões.

  1. ip
  2. ss
  3. Abaixo de / sys / class / net será um diretório para cada NIC em seu sistema, repleta de arquivos contendo informações de rede. uma. Muitos dos utilitários de linha de comando simplesmente usam essa saída e a reformatam.
    b. / proc / net tem muita informação.
    c. Por exemplo, o comando arp -na pode ser totalmente replicado por cat /proc/net/arp
  4. iptables
por 07.06.2016 / 08:50