1

I've tried to create a bash script to show all available local IP addresses. Since the normal ping option can't go quicker than 1 second per IP address and fping shows too much output when executed in a for loop, I tried to do it like this:

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

But every time I try to run the little script, it shows that

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'

1 Answers1

0

There are a number of syntax errors in your script; I'll go over those at the end. But first, it looks there's a simpler way to scan a /24 subnet, with fping's -g (generator) option. I don't have fping installed to test with, but from the documentation, this should work:

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

The ${gateway%.*} part takes the entered gateway IP, an trims starting at the last "." (i.e. the last octet). So if gateway is "192.168.0.254", that's "192.168.0". The script then adds ".0/24" to it to give "192.168.0.0/24" as the subnet string.

Problems in the original script:

  • Start your scripts with an appropriate shebang line. Generally, that'll be #!/bin/bash or #!/usr/bin/env bash. You'll also see #!/bin/sh, but that can cause trouble if you use any bash syntax extensions in your script. If you don't know the subtleties of bash vs plain sh syntax, stick with a bash shebang.

  • Your for statement is missing its do. It should be for ip in $(seq 1 254); do.

  • bash v3 doesn't allow negative string indexes (e.g. ${gateway::-1}). If you have bash version 4, that'll work; if you have v3, you need to subtract one from the string length: ${gateway::${#gateway}-1}. Or you could use the trim-from-end operator, %, as I did in my code above. If you use ${gateway%.*}, that'll remove the last "." as well as the number, so you need to add it back. Other advantage is this'll also work if the final octet is more than one digit (e.g. some people put their routers at .254 for some reason).

  • You should almost always put double-quotes around variable references, to avoid various forms of misparsing of spaces, wildcards, etc. In this case it's probably safe, but I'd still avoid it. But in your script, you're counting on word splitting to have each address passed as a separate argument to fping. The best-practise way to do this in a shell script is to use an array rather than a plain variable, with each argument being a separate array element. The syntax for this is a bit messy, but the basic operations are these:

    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
    
  • You can't use spaces in an assignment (unless you quote or escape them, in which case they're part of the assigned string). When you use var = something, the shell treats that as running the command var, with = and something as arguments. So your assignment should look something like this:

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

    ...except that as I said above, you should be using an array. So set it to empty before the loop (allips=()), and then use:

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

    And then after the loop, use it like this:

    fping -c1 -t500 -a "${allips[@]}" > /dev/null
    
Gordon Davisson
  • 11,036
  • 3
  • 27
  • 33
  • thank you very, very much. I am new to Linux and bash and these tips will definetely help me a lot. Especially thanks for the "." seperation, I knew that it was possible but just didn't know how to do it. Really appreciate it :) have a good day –  Jan 10 '18 at 22:18
  • @Kawoo Glad it helped. BTW, I'll recommend a couple of good resources for shell scripting: [shellcheck.net](https://www.shellcheck.net) can point out a lot of common mistakes and syntax errors, and [Greg's bashFAQ](http://mywiki.wooledge.org/BashFAQ) answers a lot of common questions. – Gordon Davisson Jan 10 '18 at 22:48