#!/bin/bash # ----------------------------------------------------------------- # ipset set listing wrapper script # ----------------------------------------------------------------- # Examples: # $0 - no args, just list set names # $0 -c - show all set names and their member sum # $0 -t - show all sets, but headers only # $0 -c -m setA setB - show members and sum of setA & setB # $0 -a -c -d : - show all sets members, sum and use `:' as entry delimiter # $0 -c -m -d $'\n' setA - show members and sum of setA, delim with newline # ----------------------------------------------------------------- # ----------------------------------------------------------------- # Modify here # ----------------------------------------------------------------- # path to ipset ipset="/sbin/ipset" # default delimiter character delim=" " # default read timeout TMOUT=30 # ----------------------------------------------------------------- set -f shopt -s extglob show_all=0 show_count=0 show_members=0 headers_only=0 names_only=0 in_header=0 i=0 [[ -x $ipset ]] || { printf "ipset binary \`%s' does not exist, or is not executable" "$ipset" exit 1 } while (($#)); do # parse cmd-line options case "$1" in -h) printf "ipset set listing wrapper script\n" printf "%s [-{a|c|h|m|n|r|s|t}] [...] [-d char] [set-name] [...]\n" "${0//*\//}" exit 0 ;; -a) show_all=1 shift ;; -c) show_count=1 shift ;; -m) show_members=1 shift ;; -n) names_only=1 shift ;; -t) headers_only=1 arr_par[i++]="$1" shift ;; -s|-r) arr_par[i++]="$1" shift ;; -d) if [[ -z $2 ]]; then printf "delim character is missing\n" >&2 exit 2 else if ((${#2} > 1)); then printf "only one character is allowed as delim\n" >&2 exit 2 fi delim="$2" shift 2 fi ;; -o) if [[ $2 != plain ]]; then printf "only plain output is supported\n" >&2 exit 2 else shift 2 fi ;; -\!|-f) printf "unsupported option: \`$1'\n" >&2 exit 2 ;; *) break esac done # option logic if ((names_only && headers_only)); then printf "options -n and -t are mutually exclusive\n" >&2 exit 2 elif ((headers_only)); then if ((show_count || show_members || show_all)); then printf "options -t and -a|-c|-m are mutually exclusive\n" >&2 exit 2 fi elif ((names_only)); then if ((show_count || show_members || show_all)); then printf "options -n and -a|-c|-m are mutually exclusive\n" >&2 exit 2 fi "$ipset" l -n exit $? fi # sets to work on (no arg means all sets) i=0 if [[ $1 ]]; then arr_opts=("$@") else while IFS=$'\n' read -r; do arr_opts[i++]="$REPLY" done < <("$ipset" l -n) i=0 fi # read sets for x in "${!arr_opts[@]}"; do while read -r; do case "$REPLY" in "") : ;; Name:*) # header opened if ((in_header)); then printf "unexpected entry: \`%s' - header not closed?\n" "$REPLY" >&2 exit 1 fi i=0 in_header=1 printf "\n%s\n" "$REPLY" ;; @(Type|Header|Size in memory|References):*) # header entry if ((headers_only || show_all)); then printf "%s\n" "$REPLY" fi ;; Revision:*) # header entry (closes header on -t) if ((headers_only)); then in_header=0 printf "%s\n" "$REPLY" elif ((show_all)); then printf "%s\n" "$REPLY" fi ;; Members:*) # header entry (closes header if not -t) in_header=0 if ((show_all)); then printf "%s\n" "$REPLY" fi ;; *) # member entry if ((in_header)); then printf "unexpected entry: \`%s'\n" "$REPLY" >&2 exit 1 fi if ((show_members || show_all)); then printf "%s$delim" "$REPLY" fi let i+=1 esac done < <("$ipset" l "${arr_opts[x]}" "${arr_par[@]}") if ((show_members || show_all)) && [[ $delim != $'\n' ]]; then printf "\n" fi if ((show_count)); then printf "Member count: %d\n" $i fi done