adicionando string e variável a outra variável no script bash

1

Eu tentei criar um script bash para mostrar todos os endereços IP locais disponíveis. Como a opção de ping normal não pode ir mais rápido que 1 segundo por endereço IP e fping mostra saída demais quando executada em um loop for, tentei fazer assim:

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

Mas toda vez que eu tento rodar o pequeno roteiro, isso mostra que

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'
    
por Kawoo 06.01.2018 / 13:36

1 resposta

0

Existem vários erros de sintaxe no seu script; Eu vou passar por cima deles no final. Mas primeiro, parece que há uma maneira mais simples de examinar uma sub-rede / 24, com a opção fping ' -g (gerador). Eu não tenho o fping instalado para testar, mas da documentação , isso deve funcionar:

#!/bin/bash
read -p "Enter Gateway IP Address: " gateway
fping -c1 -t500 -a -g "${gateway%.*}.0/24" > /dev/null

A parte ${gateway%.*} leva o IP do gateway inserido, um trim a partir do último "." (isto é, o último octeto). Então, se o gateway é "192.168.0.254", isso é "192.168.0". O script adiciona ".0 / 24" a ele para fornecer "192.168.0.0/24" como a string de sub-rede.

Problemas no script original:

  • Inicie seus scripts com uma linha shebang apropriada. Geralmente, isso será #!/bin/bash ou #!/usr/bin/env bash . Você também verá #!/bin/sh , mas isso pode causar problemas se você usar qualquer extensão de sintaxe bash em seu script. Se você não conhece as sutilezas da sintaxe bash vs sh simples, fique com um bash shebang.

  • Sua instrução for está sem sua do . Deve ser for ip in $(seq 1 254); do .

  • bash v3 não permite índices de string negativos (por exemplo, ${gateway::-1} ). Se você tiver a versão 4 do bash, isso funcionará; se você tiver v3, precisará subtrair um do tamanho da string: ${gateway::${#gateway}-1} . Ou você poderia usar o operador trim-from-end, % , como fiz no meu código acima. Se você usar ${gateway%.*} , isso removerá o último "." bem como o número, então você precisa adicioná-lo novamente. Outra vantagem é que isso também funcionará se o octeto final tiver mais de um dígito (por exemplo, algumas pessoas colocam seus roteadores em 0,254 por algum motivo).

  • Você deve quase sempre colocar aspas duplas em torno de referências de variáveis, para evitar várias formas de interpretação incorreta de espaços, caracteres curinga, etc. Nesse caso, é provável que seja seguro, mas ainda assim evitá-lo. Mas no seu script, você está contando com a divisão de palavras para que cada endereço seja passado como um argumento separado para fping . A melhor maneira prática de fazer isso em um script de shell é usar uma matriz em vez de uma variável simples, com cada argumento sendo um elemento de matriz separado. A sintaxe para isso é um pouco confusa, mas as operações básicas são estas:

    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
    
  • Você não pode usar espaços em uma atribuição (a menos que você os cite ou os escape, caso em que eles são parte da string atribuída). Quando você usa var = something , o shell trata isso como executar o comando var , com = e something como argumentos. Então, sua tarefa deve ser algo assim:

    allips="$allips ${gateway::-1}$ip"
    

    ... exceto que, como eu disse acima, você deve estar usando uma matriz. Então, defina para esvaziar antes do loop ( allips=() ) e, em seguida, use:

    allips+=("${gateway%.*}.$ip")
    

    Depois do loop, use-o assim:

    fping -c1 -t500 -a "${allips[@]}" > /dev/null
    
por 07.01.2018 / 22:46