From: Born Without <blackhole@airpost.net>
To: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Cc: Jan Engelhardt <jengelh@inai.de>,
"netfilter@vger.kernel.org" <netfilter@vger.kernel.org>
Subject: Re: Wrapper script for ipset listing
Date: Wed, 09 Jan 2013 07:52:44 +0100 [thread overview]
Message-ID: <50ED13BC.6010005@airpost.net> (raw)
In-Reply-To: <alpine.DEB.2.00.1301070852290.591@blackhole.kfki.hu>
[-- Attachment #1: Type: text/plain, Size: 1442 bytes --]
On 07.01.2013 08:59, Jozsef Kadlecsik wrote:
> On Sun, 6 Jan 2013, Jan Engelhardt wrote:
>
>> On Sunday 2013-01-06 04:50, Born Without wrote:
>>>>> As I was missing those features in the ipset set listing capabilities:
>>>>>
>>>>> - show sum of set members
>>>>> - suppress listing of headers
>>>>> - choose a delimiter character for separating member entries
>>>>>
>>>>> I wrote a little wrapper script (for the bash shell) to support them.
>>>>> For those who like, you'll find it attached.
>>>>
>>>> There's libipset, with which this task should be achievable to the
>>>> maximum customizable degree without involving ugly text parsing with sh.
>>>
>>> good you mention libipset, because not even the man page does, nor does any
>>> documentation or similar exist.
>>
>> I have taken Joszef into Cc..
[...]
>
> In order to parse the output produced by ipset, one should take into
> account the followings:
>
> - New header elements may appear but the header part is always
> started by "Name:" and ended by "Members:".
> - New value parameters may appear but those are appended to the existing
> ones.
>
> If those "rules" are taken into account, then shell/perl/etc scripts can
> safely parse the output.
>
Thank you Joszef for that information.
I've taken it into account and adapted the script.
Also added:
-a parameter to act just like 'ipset list', but with whitespace as
default delim.
comments and examples.
Best regards
[-- Attachment #2: ipset_list.bash --]
[-- Type: text/plain, Size: 3920 bytes --]
#!/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
next prev parent reply other threads:[~2013-01-09 6:52 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-05 16:05 Wrapper script for ipset listing Born Without
2013-01-05 16:16 ` Born Without
2013-01-06 4:54 ` Born Without
2013-01-05 17:10 ` Jan Engelhardt
2013-01-06 3:50 ` Born Without
2013-01-06 20:06 ` Jan Engelhardt
2013-01-07 7:59 ` Jozsef Kadlecsik
2013-01-09 6:52 ` Born Without [this message]
2013-01-09 11:52 ` Pablo Neira Ayuso
2013-01-10 12:53 ` Born Without
2013-01-10 15:01 ` Eliezer Croitoru
2013-01-10 21:18 ` Born Without
2013-01-10 15:19 ` Jozsef Kadlecsik
2013-01-10 21:15 ` Born Without
2013-01-10 21:37 ` Born Without
2013-01-11 8:19 ` Born Without
2013-01-21 8:31 ` Born Without
2013-01-21 8:55 ` Jozsef Kadlecsik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50ED13BC.6010005@airpost.net \
--to=blackhole@airpost.net \
--cc=jengelh@inai.de \
--cc=kadlec@blackhole.kfki.hu \
--cc=netfilter@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.