#!/bin/ksh93 # License: CDDL 1.0 # Copyright (c) 2017 Jens Elkner. All Rights Reserved. # exec time in seconds on a Intel(r) Xeon(r) CPU E5-2667 v2 @ 3.30GHz # TMPFILE PIPED COPROC HEREDOC # # ksh93 t+_illumos S11 17.14 20.20 15.40 18.00 # ksh93 u+ self S11 18.74 22.43 17.91 19.80 # ksh93 u+ S11 20.35 23.84 18.92 21.29 # bash 4.1.17(1) S11 125.12 - 160.23 681.14 # zsh 5.0.7 S11 174.02 90.79 91.05 186.89 # # ksh93 u+ Ubuntu 21.71 27.68 21.42 22.06 # bash 4.3.30(1) Ubuntu 68.67 - 145.94 93.81 # zsh 5.0.7 Ubuntu 153.79 126.70 126.95 158.34 # # nodeJS 6.9.1 S11 6.55 # Test file: 6944468 lines (752238588 byte). 6944468 are relevant (grepped) # containing 8285 unique v4 IPs and whereby 2476 IPs have more than 3 fails # (causing in summary 1575953 fails). More Details: # - http://iks.cs.ovgu.de/~elkner/osol/tmatrix-base.sh # - http://iks.cs.ovgu.de/~elkner/osol/tmatrix-base.js # S11 == Solaris 11.3 SRU 16.3 (64bit) (native NGZ) # Ubuntu == Ubuntu 15.10 (64bit) (native NGZ aka lxc) # illumos == illumos gate version compiled and ran on S11 # self == github master version with min. patches + xarch=sse3 + other opts # NOTE: only the illumos version uses "handcrafted" lib{sum,dll,ast,cmd,shell). # NOTES (S11) wrt. the while-read-loop: # Used the TEMPFILE method above, because this is the only variant, which # works in all shells without adjustments. # ksh93 u+: # - ~ +0.2s slower when using heredoc # - ~ +3.5s slower with streaming (|) # - fastest (~ -1.43s) if reading from a co process (|&) # zsh: # - with heredoc ~13s slower # - much faster (~ -83s) with streaming or co proc (~ -82.97s) # bash: # - streaming does not work because of stupid "last pipeline in subshell" # - coproc, i.e. redirect its output via <&${foo[0]} explodes to +35.11s # - heredoc goes mad: ~ +9min typeset -i N_IGNORE=3 if [[ -n ${ZSH_VERSION} ]]; then setopt AUTO_CD no_POSIX_CD setopt no_IGNORE_BRACES no_IGNORE_CLOSE_BRACES no_MAGIC_EQUAL_SUBST \ CASE_MATCH no_NOMATCH no_REMATCH_PCRE MULTIBYTE UNSET \ GLOB no_GLOB_ASSIGN no_GLOB_DOTS GLOB_SUBST CASE_GLOB \ no_EXTENDED_GLOB KSH_GLOB no_SH_GLOB setopt no_GLOBAL_EXPORT setopt no_C_BASES no_C_PRECEDENCES DEBUG_BEFORE_CMD FUNCTION_ARGZERO \ LOCAL_LOOPS no_MULTIOS setopt KSH_ARRAYS KSH_TYPESET KSH_OPTION_PRINT LOCAL_OPTIONS LOCAL_TRAPS \ POSIX_IDENTIFIERS POSIX_STRINGS POSIX_TRAPS \ no_SH_FILE_EXPANSION SH_NULLCMD no_SH_OPTION_LETTERS SH_WORD_SPLIT typeset -A C # zsh sucks: ${!vname[@]} , ${ cmd ; } , (( vname )) and [un]quoting # do not work {correctly|at all|reliably}. So we need to use ancient # (less performant/unsafe) statements and workarounds =8-( else typeset -Ai C fi if [[ -n ${BASH_VERSION} ]]; then typeset ARRAY='-a' alias print=echo else typeset ARRAY='-A' fi # Since bash has no 'print' builtin, on linux it would call some other bullshit. # Therefore we use printf all over the place (but wouldn't do in ksh|zsh). SECONDS=0.0 typeset -i N=0 T=1 K S FILE="$1" #TF=`mktemp /tmp/failXXXXXX.log` #[[ -z $TF ]] && exit 1 #trap "rm -f ${TF}" EXIT #+ grep 'Failed password' ${FILE:-/var/log/authlog} >>"${TF}" TF=` + grep 'Failed password' ${FILE:-/var/log/authlog} ` #coproc foo { + grep 'Failed password' ${FILE:-/var/log/authlog} ; } # bash #coproc + grep 'Failed password' ${FILE:-/var/log/authlog} # zsh #+ grep 'Failed password' ${FILE:-/var/log/authlog} |& # ksh coproc #+ grep 'Failed password' ${FILE:-/var/log/authlog} | \ while read ${ARRAY} A ; do #while read -p ${ARRAY} A ; do (( N == 10000 )) && N=0 && printf "# ${T}0000 in ${SECONDS}s\n" && (( T++ )) (( N++ )) if [[ ${A[13]} == 'from' ]]; then (( C[${A[14]}]++ )) continue elif [[ ${A[12]} == 'from' ]]; then (( C[${A[13]}]++ )) continue fi print "# Skipping '${A[@]}'"; #done #done <${TF} #done <&${foo[0]} done <<<"${TF}" (( T-- )) (( T*=10000 )) (( T+=N )) [[ -n ${ZSH_VERSION} ]] && A=( ${(k)C[@]} ) || A=( ${!C[*]} ) print "#" print "# Scanned in $T lines with ${#A[@]} unique IPs within ${SECONDS}s with" typeset X= Y= Z= M= K=0 S=0 for I in ${A[@]} ; do N=${C[${I}]} (( $N <= $N_IGNORE )) && continue Y+=` printf '%-4d %s' $N $I `'\n' (( K++ )) [[ $I =~ \: ]] && Z=` printf "%-32s %d" $I $N ` || \ X+=` printf '%03d.%03d.%03d.%03d %d' ${I//./ } $N `'\n' (( S+=N )) done print "# $K IPs with more than ${N_IGNORE}x fails (caused in summary $S" \ 'fails).\n\n# Count\tIP\n' print -n "$Y" | sort -n print '\n# IP Count\n' print -n "$X" | sort print -n "$Z" | sort print "# Job complete after ${SECONDS}s"