You are not logged in.

#1476 2011-06-27 03:24:04

GraveyardPC
Member
Registered: 2008-11-29
Posts: 99

Re: Post your handy self made command line utilities

Something extremely simple, but quite useful (tailored for Arch):

#!/bin/bash
# -- MAC Sweep --
# Ping sweeps a CIDR range for MAC addresses.

. /etc/rc.conf
. /etc/rc.d/functions

sweep() {
  stat_busy "Broadcasting to ${1}"
  fping -c 1 -g $1 &>/dev/null
  if [[ $? == 127 ]]; then
    stat_fail
    printhl "Missing fping!"
    echo "   install using 'pacman -S fping'"
    exit 1
  else
    stat_done
  fi
}

list() {
  stat_busy "Waiting for responses"
  result=$(arp)
  if [[ $? == 127 ]]; then
    stat_fail
    printhl "Missing arp (net-tools)!"
    echo "   install using 'pacman -S net-tools'"
    exit 1
  else
    stat_done
    echo
  fi
  
  _IFS=$IFS; IFS=$'\n'
  for line in $result; do IFS=" "; show $line; IFS=$'\n'; done
  IFS=$_IFS
}

show() {
  if [[ "${1}" == "Address" ]]; then
    echo -e "   ${1}\t${3}"
    return
  elif [[ "${2}" != "(incomplete)" ]]; then
    printhl "${1}\t${3}"
  fi
}

sweep $1
list

Example:

user@server:~$ macsweep 10.10.10.0/24
:: Broadcasting to 10.10.10.0/24                                                        [DONE] 
:: Waiting for responses                                                                [DONE] 

   Address         HWaddress
 > 10.10.10.2      00:0f:b5:57:98:c4 
 > 10.10.10.1      c8:4c:75:4e:69:5e 
 > 10.10.10.104    d0:df:9a:1a:90:05 

Last edited by GraveyardPC (2011-06-27 03:31:20)

Offline

#1477 2011-06-27 10:09:32

rwd
Member
Registered: 2009-02-08
Posts: 664

Re: Post your handy self made command line utilities

GraveyardPC wrote:

Something extremely simple, but quite useful (tailored for Arch):

#!/bin/bash
# -- MAC Sweep --
# Ping sweeps a CIDR range for MAC addresses.
....

Nice script but most people use nmap for this I think.

Offline

#1478 2011-06-27 21:33:04

shua
Member
Registered: 2010-08-12
Posts: 3

Re: Post your handy self made command line utilities

Two bash scripts I worked up out of anger. (maybe not the best, but I still use them)

I wrote my own (simpler) xdg-open because mine kept giving me trouble opening the wrong programs.

#!/bin/sh

echo $1
if [ $1="/*" ]; then
file="$1"
else
file="`pwd`/$1"
fi

type="`xdg-mime query filetype "$file" | sed "s|; .*||g"`"


case $type in
text/*)
  /usr/bin/urxvt -e /usr/bin/nano "$file"
  break
  ;;
application/x-directory)
  /usr/bin/urxvt -cd "$file"
  break
  ;;
application/[x-bzip2,x-gzip])
  /usr/bin/urxvt -e /usr/bin/tar -xf "$file"
  break
  ;;
application/vnd.ms-office)
  /usr/bin/libreoffice "$file"
  break
  ;;
image/*)
  /usr/bin/feh "$file"
  break
  ;;
video/*)
  /usr/bin/vlc "$file"
  break
  ;;
*)
  /usr/bin/chromium "$file"
  break
  ;;
esac

This was I script I made for starting wine programs (steam) because I got too lazy to type in the location even with wildcards to speed it up.

#!/bin/sh

help () {
echo "USAGE: wineprog [PROGRAM]

PROGRAMS are:
        "Steam"         Valve game distribution
                "Steam-tf2"     Team Fortress 2
                "Steam-hl2"     Half-life 2
                "Steam-portal"  Portal
                "Steam-hl2e1"   Half-life 2 Episode 1
                "Steam-hl2e2"   Half-life 2 Episode 2
        "tf2b"          Team Fortress 2 beta"
}

steam="/home/shua/.wine/drive_c/Program Files (x86)/Steam/Steam.exe"
steamo="-novid -window -w 1280 -h 1024 -console -silent -noforcemaccel -noforcemparms -nojoy"

case "$1" in
        Steam-hl2)
                wine "$steam" -applaunch 220 $steamo
                break
                ;;
        Steam-hl2e1)
                wine "$steam"  -applaunch 380 $steamo
                break
                ;;
        Steam-hl2e2)
                wine "$steam"  -applaunch 420 $steamo
                break
                ;;
        Steam-tf2)
                wine "$steam"  -applaunch 440 $steamo
                break
                ;;
        Steam-portal)
                wine "$steam"  -applaunch 400 $steamo
                break
                ;;
        Steam)
                wine "$steam"
                break
                ;;
        tf2b)
                wine /home/shua/.wine/drive_c/Program\ Files\ \(x86\)/Team\ Fortress\ 2/RUN_TF2.exe
                break
                ;;
        *)
                help
                ;;
esac

Offline

#1479 2011-06-27 21:41:47

GraveyardPC
Member
Registered: 2008-11-29
Posts: 99

Re: Post your handy self made command line utilities

rwd wrote:
GraveyardPC wrote:

Something extremely simple, but quite useful (tailored for Arch):

#!/bin/bash
# -- MAC Sweep --
# Ping sweeps a CIDR range for MAC addresses.
....

Nice script but most people use nmap for this I think.

Yeah, you can use:

nmap -sP -n xxx.xxx.xxx.xxx/xx

But, it requires root privileges.

Offline

#1480 2011-06-28 23:28:06

Barrucadu
Member
From: York, England
Registered: 2008-03-30
Posts: 1,158
Website

Re: Post your handy self made command line utilities

I seem to be writing many scripts lately, now here is one to manage mounting/unmounting remote shares.

#!/bin/zsh

# This is a config file containing an array of remotes to mount
# Format: SHARES=(mountpoint:user:host:remotepath:port ...)
# Example: SHARES=(media:barrucadu:eihort:/media:22 share:barrucadu:eihort:/share:22)
. $XDG_CONFIG_HOME/remotes/config

# Check if a remote is mounted
# ARGUMENTS: mountpoint, remote
function mounted ()
{
    mountpoint=$1
    remote=$2

    mount | grep -q "$remote on $mountpoint"
}

# Mount a remote
# ARGUMENTS: mountpoint, remote, port
function domount ()
{
    mountpoint=$1
    remote=$2
    port=$3

    sshfs -C -p $port $remote $mountpoint
}

# Unmount a remote
#ARGUMENTS: mountpoint
function doumount ()
{
    mountpoint=$1

    fusermount -u $mountpoint
}

if [[ $1 == "help" ]] || [[ $1 == "" ]]; then
    echo "USAGE: remotes <command> <remote>"
    echo
    echo "Commands:"
    echo "    list   - List all remotes, indicating which are mounted"
    echo "    mount  - Mount the specified remote (if not already mounted)"
    echo "    umount - Unmount the specified remote (if mounted)"
    echo "    all    - Mount all unmounted remotes"
    echo "    none   - Unmount all mounted remotes"
    echo
    echo " ~ Michael Walker <mike@barrucadu.co.uk>"
else
    action=$1
    for share in $SHARES; do
        mount=`echo $share | sed 's/\(.*\):\(.*\):\(.*\):\(.*\):\(.*\)/\1/'`
        ruser=`echo $share | sed 's/\(.*\):\(.*\):\(.*\):\(.*\):\(.*\)/\2/'`
        rhost=`echo $share | sed 's/\(.*\):\(.*\):\(.*\):\(.*\):\(.*\)/\3/'`
        rpath=`echo $share | sed 's/\(.*\):\(.*\):\(.*\):\(.*\):\(.*\)/\4/'`
        rport=`echo $share | sed 's/\(.*\):\(.*\):\(.*\):\(.*\):\(.*\)/\5/'`
        
        name=$rhost-$mount
        mountpoint=/share/$name
        remote=$ruser@$rhost:$rpath

        if [[ $action == "list" ]]; then
            # List all remotes
            if `mounted $mountpoint $remote`; then
                echo "[MOUNTED] $remote:$rport on $mountpoint ($name)"
            else
                echo "          $remote:$rport on $mountpoint ($name)"
            fi

        elif [[ $action == "mount" ]]; then
            # Mount the remote
            if [[ $2 == $name ]] && ! `mounted $mountpoint $remote`; then
                domount $mountpoint $remote $rport
            fi

        elif [[ $action == "umount" ]]; then
            # Unmount the remote
            if [[ $2 == $name ]] && `mounted $mountpoint $remote`; then
                doumount $mountpoint
            fi

        elif [[ $action == "all" ]]; then
            # Mount all unmounted remotes
            if ! `mounted $mountpoint $remote`; then
                domount $mountpoint $remote $rport
            fi
            
        elif [[ $action == "none" ]]; then
            # Unmount all mounted remotes
            if `mounted $mountpoint $remote`; then
                doumount $mountpoint
            fi
        fi
    done
fi

It has a simple config file at $XDG_CONFIG_HOME/remotes/config, here is mine for example:

SHARES=(media:barrucadu:eihort:/srv/media:22 share:barrucadu:eihort:/srv/share:22 http:barrucadu:eihort:/srv/http:22 misc:barrucadu:yuggoth:/srv/http/barrucadu.co.uk/misc:22)

The format is "shortname:remoteuser:host:remotepath:sshport", and things are mounted at "/share/host-shortname".

Example:

barrucadu on azathoth in ~ [branch: master]
 >>>  remotes list
          barrucadu@eihort:/srv/media:22 on /share/eihort-media (eihort-media)
          barrucadu@eihort:/srv/share:22 on /share/eihort-share (eihort-share)
          barrucadu@eihort:/srv/http:22 on /share/eihort-http (eihort-http)
          barrucadu@yuggoth:/srv/http/barrucadu.co.uk/misc:22 on /share/yuggoth-misc (yuggoth-misc)

barrucadu on azathoth in ~ [branch: master]
 >>>  remotes mount eihort-media

barrucadu on azathoth in ~ [branch: master]
 >>>  remotes list
[MOUNTED] barrucadu@eihort:/srv/media:22 on /share/eihort-media (eihort-media)
          barrucadu@eihort:/srv/share:22 on /share/eihort-share (eihort-share)
          barrucadu@eihort:/srv/http:22 on /share/eihort-http (eihort-http)
          barrucadu@yuggoth:/srv/http/barrucadu.co.uk/misc:22 on /share/yuggoth-misc (yuggoth-misc)

barrucadu on azathoth in ~ [branch: master]
 >>>  remotes all

barrucadu on azathoth in ~ [branch: master]
 >>>  remotes list
[MOUNTED] barrucadu@eihort:/srv/media:22 on /share/eihort-media (eihort-media)
[MOUNTED] barrucadu@eihort:/srv/share:22 on /share/eihort-share (eihort-share)
[MOUNTED] barrucadu@eihort:/srv/http:22 on /share/eihort-http (eihort-http)
[MOUNTED] barrucadu@yuggoth:/srv/http/barrucadu.co.uk/misc:22 on /share/yuggoth-misc (yuggoth-misc)

barrucadu on azathoth in ~ [branch: master]
 >>>  remotes
USAGE: remotes <command> <remote>

Commands:
    list   - List all remotes, indicating which are mounted
    mount  - Mount the specified remote (if not already mounted)
    umount - Unmount the specified remote (if mounted)
    all    - Mount all unmounted remotes
    none   - Unmount all mounted remotes

 ~ Michael Walker <mike@barrucadu.co.uk>

It currently uses sshfs (though it's pretty simple to change, there are three functions to handle mounting, unmounting, and checking if mounted). To mount something it requires that the directory exists and is writeable by you.

Offline

#1481 2011-07-02 19:47:29

Firestone
Member
From: Amsterdam
Registered: 2009-07-26
Posts: 20

Re: Post your handy self made command line utilities

Two bash scripts I wrote because I couldn't find an existing application that did what I wanted.

CLI Channel Selector for watching TV by PVR
This script allows the user to watch TV and switch channels in any mediaplayer with PVR support by using a simple CLI.
Features include:

  • Interactive mode for easy and live channel switching, or

  • Specify device

  • Specify channel

  • Specify frequency

  • Specify arguments for video player

  • List channels by name

#!/bin/bash
# Commandline Analog TV Channel Selector for PVR
# Default set Dutch cable tv by UPC Amsterdam and VLC
#
# chansel [-hilv] [-a <arg> ] [-d <device> ] [-c <channel>] [-f <frequency> ] 
#
# -a : specify vlc arguments
# -c : specify channel
# -d : specify device
# -f : specify frequency
# -h : display help
# -i : interactive mode
# -l : print channel list
# -v : display version
#
#
# Xander Wilcke 
# w.x.wilcke@student.vu.nl
# https://www.few.vu.nl/~wwe300/scripts.html 
#
# Released by GPL
#
# JUN 2011 - v0.3
#    * made video app independent
#    * now has ivtv-tune as dependency
#    * added device selection
#    * added real time channel switching
#    * now kills video app on quit
#    * now defaults to quiet output
#    * rewriten interactive mode to use specifiers
#    * rewriten frequency table to comply with ivtv-tune
#
# JUN 2010 - v0.2
#    * added arguments to complement interactive mode
#    * added frequency specification
#    * added help
#    * added vlc arguments specification
#    * rewriten channel to frequency conversion as case
#    * added variable for easy editing
#    * added input checks
#    * added requirements check
#    * added error system
#
# DEC 2008 - v0.1
#    * added channel list
#    * added interactive mode only
#    * added channel to frequency conversion
#

declare -r VERSION="v0.3"

declare -ir FREQ_FLOOR=0
declare -ir FREQ_CEILING=999
declare -ir CHAN_FLOOR=1
declare -ir CHAN_CEILING=22
declare -ir DISPLAY_ID=0
declare -r  DEFAULT_DEVICE="/dev/video1"
declare -r  VIDEO_APP="/usr/bin/vlc"        # defaults to VLC
declare -r  VIDEO_APP_OPTIONS="pvr:// :pvr-device="    # device and mode select for video app
declare -r  DEFAULT_OPTIONS="--qt-minimal-view --no-qt-privacy-ask --no-qt-name-in-title --disable-screensaver --zoom 1.0" 
declare -i  PID=$$


# print channel list
# set up for UPC Amsterdam
listChannels() {
    echo
    echo "Channel List"
    echo "1  - Nederland 1"
    echo "2  - Nederland 2"
    echo "3  - Nederland 3"
    echo "4  - RTL 4"
    echo "5  - RTL 5"
    echo "6  - SBS6"
    echo "7  - RTL 7"
    echo "8  - Veronica"
    echo "9  - Net 5"
    echo "10 - AT5"
    echo "11 - RTV-NH"
    echo "12 - RTL 8"
    echo "13 - VRT"
    echo "14 - Canvas"
    echo "15 - National Geographic Channel"
    echo "16 - Discovery Channel"
    echo "17 - BBC 1"
    echo "18 - BBC 2"
    echo "19 - BBC World"
    echo "20 - CNN"
    echo "21 - Comedy Central"
    echo "22 - TMF"
    echo 
}

# link channel to frequency
getChan() {
    local frequency

    case "$1" in
        "1")
            frequency=216
            ;;
        "2")
            frequency=184
            ;;
        "3")
            frequency=192
            ;;
        "4")
            frequency=224
            ;;
        "5")
            frequency=232
            ;;
        "6")
            frequency=280
            ;;
        "7")
            frequency=240
            ;;
        "8")
            frequency=672
            ;;
        "9")
            frequency=272
            ;;
        "10")
            frequency=512
            ;;
        "11")
            frequency=264
            ;;
        "12")
            frequency=536
            ;;
        "13")
            frequency=200
            ;;
        "14")
            frequency=208
            ;;
        "15")
            frequency=544
            ;;
        "16")
            frequency=800
            ;;
        "17")
            frequency=784
            ;;
        "18")
            frequency=792
            ;;
        "19")
            frequency=752
            ;;
        "20")
            frequency=248
            ;;
        "21")
            frequency=560
            ;;
        "22")
            frequency=288
            ;;
        *)
            printError "input not recognized: $input"
            echo -ne "continue"

            read dummy

            goInteractive
            ;;
    esac

    echo "$frequency"
}


# interactive mode
goInteractive() {
    declare appRunning

    echo "CLI TV Channel Selector for PVR"
    echo "Enter 'list' for channel list or 'q' to quit"
    echo -n "Enter channel number(1-22) : "

    read input

    case "$input" in
        "list")
            listChannels
            
            echo -ne "continue?"

            read dummy
            ;;
        "q")
            kill -9 $PID 
            exit 0
            ;;
        *)
            if [[ $(inRange $input $CHAN_FLOOR $CHAN_CEILING) -eq 0 ]]
            then
                channel=$input
                
                if [[ $2 = false ]]
                then
                    mode="chan"

                    appRunning=true
                else
                    mode="switchchan"
                fi
                    
                program $mode $1 $channel 0 $3
            else
                printError "input not recognized: $input"
                echo -ne "continue?"

                read dummy
            fi
            ;;
    esac

    clear

    goInteractive $1 $appRunning $3
}


# manage variables
program() {
    declare -i freq
    declare -ir OPTION_INDEX=4
    declare options
    
    if [[ $5 = true ]]
    then
        goInteractive $2 false $options
    else

        if [[ $1 == "chan" || $1 == "switchchan" ]]
         then
            freq=$(getChan $3)
        else
            freq=$4
        fi

        if [[ ! $6 == "" ]]
        then
            for(( i=$OPTION_INDEX; i<=$#; i++ ))
            do
                options="$options ${!i}"
            done
        else
            options=$DEFAULT_OPTIONS
        fi


        setFreq $2 $freq

        if [[ $1 != "switchchan" ]]
        then
            runPlayer $2 $options
    
        fi
    fi
}

# set device and frequency
setFreq() {
    /usr/bin/ivtv-tune -d $1 -f $2 
}

# run player with parameters
runPlayer() {
    export DISPLAY=:$DISPLAY_ID && eval "($VIDEO_APP $2 $VIDEO_APP_OPTIONS"$1" 2> /dev/null &)"
    PID=$!
}

# print help
printHelp() {
    echo "NAME"
    echo "     chanSel - Commandline TV Channel Selector for PVR"
    echo

    echo "SYNTAX"
    echo "     chansel [-hilv] [-a <arg> ] [-d <device>] [-c <channel>] [-f <frequency> ]"
    echo

    echo "VERSION"
    echo "     version $VERSION"
    echo

    echo "OPTIONS"
    echo "    -a"
    echo "     specify arguments for video player"
    echo
    echo "    -c"
    echo "     specify channel"
    echo
    echo "    -d"
    echo "     specify device, e.g. /dev/video0"
    echo
    echo "    -f"
    echo "     specify frequency in MHz, where 1 < frequency < 999"
    echo
    echo "    -h"
    echo "     display this help and exit"
    echo
    echo "    -i"
    echo "     interactive mode for easy channel switching"
    echo
       echo "    -l"
    echo "     display list of availible channels"
    echo
    echo "    -v"
    echo "     print version and exit"
    echo


    echo "NOTE"
    echo "    The default video player is set to VLC. This can be changed by"
    echo "    modifying the global variable VIDEO_APP. If changed, the global"
    echo "    variable VIDEO_APP_OPTIONS should be modified as well, as to"
    echo "    hold the setting that points the video player to the right mode"
    echo "    (PVR) and device, as set by DEFAULT_DEVICE or by specifying it"
    echo "    with the \"-d\" parameter."
    echo

    echo "AUTHOR"
    echo "    Xander Wilcke"
    echo "    w.x.wilcke@student.vu.nl"
    echo "    https://www.few.vu.nl/~wwe300/scripts.html"
    echo 
}


# arguments handler
arguments() {
    # -h : display help
    # -v : display version
    # -c : specify channel
    # -i : interactive mode
    # -l : print channel list
    # -d : specify device
    # -f : specify frequency
    # -a : specify additional player options
    
    declare mode=0
    declare appOptions=""
    declare appRunning=false
    declare device=$DEFAULT_DEVICE
    declare interactive=false
    declare -i channel=0
    declare -i freq=0

    while getopts ":hilvc:f:a:d:" optname
    do
        case "$optname" in
            "l")
                listChannels

                exit 0
                ;;
            "f")
                if [[ $(inRange $OPTARG $FREQ_FLOOR $FREQ_CEILING) -eq 0 ]]
                then
                    freq=$OPTARG
                    mode="freq"
                else
                    printError "Out of Bounds.\nFrequency should be between $FREQ_FLOOR and $FREQ_CEILING MHz."

                    exit 1
                fi
                ;;
            "c")
                if [[ $(inRange $OPTARG $CHAN_FLOOR $CHAN_CEILING) -eq 0 ]]
                then
                    channel=$OPTARG
                    mode="chan"
                else
                    printError "Out of Bounds.\nChannel should be between $CHAN_FLOOR and $CHAN_CEILING."

                    exit 1
                fi
                ;;
            "i")
                interactive=true
                ;;
            "a")
                appOptions=$OPTARG
                ;;
            "d")
                device=$OPTARG
                ;;
            "h")
                printHelp

                exit 0
                ;;
            "v")
                echo chansel $VERSION

                exit 0
                ;;
            "?")
                echo "Option unknown: $OPTARG"
                echo "Use -h to print help"

                exit 1
                ;;
            ":")
                echo "Option $OPTARG requires an argument"
                echo "Use -h to print help"

                exit 1
                ;;
            *)            
                echo "Unknown Error"
                echo "Use -h to print help"

                exit 1
                ;;
        esac
    done
    
    program $mode $device $channel $freq $interactive $appOptions
}

# check if input is in range
inRange() {
    if [[ $(echo $1 | grep -E "^(\+|-)?[0-9]+$") && $1 -ge $2 && $1 -le $3 ]]
    then
        echo 0     # in range
    else
        echo 1    # not in range
    fi
}

# print error
printError() {
    echo -e "ERROR :: $@"
}


# check if all required programs are installed
checkRequired() {
    if [[ ! -x $VIDEO_APP ]]
    then
        echo "ERROR :: $VIDEO_APP is required but can not be located"

        exit 1
    elif [[ ! -x /usr/bin/ivtv-tune ]]
    then
        echo "ERROR :: ivtv-tune is required but can not be located"

        exit 1
    fi
}


# init
checkRequired

if [[ -z $1 ]]    #if no argument is given
then
    arguments -i    # default
else
    arguments "${@}"
fi


# ============
# End of File
# ============

Download(.sh)


And...

CLI Automated mailcheck with custom intervals and notifier for getmail
This script allows the user to check for mail on regular intervals when using getmail.
Features include:

  • Specify arguments for getmail

  • Set delay in seconds or minutes

  • Set number of runs or let it run continuously

  • Optional visual countdown

  • Optional notification on new mail by visual notify daemon or audio file

  • Stealth mode to suppress all output

#!/bin/bash
# run getmail on a user specified time interval
# requires getmail and bc to be installed
#
# mailcheck [-dfhmqQv] [-a <arg>] [-s <delay(s)>] [-m <delay(m)>] [-n <runs>] [-p <audiofile>]
#
# -a    specify getmail arguments(default -ln)
# -d    default delay(set on default) of 60 seconds
# -f    use OSD notify
# -p    use audio notify
# -q    quiet countdown
# -Q    stealth mode to suppress further output
# -s    delay in seconds
# -m    delay in minutes
# -n    number of runs(default set to loop)
# -h    print help
# -v    print version
#
#
# Xander Wilcke 
# wex.wilcke@student.vu.nl
# https://www.few.vu.nl/~wwe300/scripts.html
#
# Released by GPL
#
#
# JUN 2011 - v0.4
#    * made stealth mode more stealthy
#    * added use of OSD notify
#    * added use of audio notify
#
#    + only audio files without spaces possible for now
#
# JUL 2010 - v0.3
#    * added arguments
#    * added minute specification
#    * added run specification
#    * added silent countdown
#    * added stealth mode
#    * modified countdown to progress bar
#    * added help function
#    * added getmail argument specification
#    * added input checks
#    * added variables for easy editing
#
# MAR 2010 - v0.2
#    * added seconds specification
#    * added countdown timer
#
# DEC 2009 - v0.1
#    * added mail check on 60 seconds delay
#

declare -r VERSION="v0.4"

declare -ir DEFAULT_DELAY=60        # delay in seconds
declare -ir DEFAULT_NR_OF_RUNS=-1    # keep running
declare -r  NOTIFY_CMD=notify-send    # command used to send notification

# display notification
processNotify() {
    declare -i newmail=0
    declare -i unseenmail=0
    declare -i totalmail=0

    declare -r MAILTAIL=$(echo "$1" | awk '$NF == "skipped"')
    
    NEWMAIL=$(echo $MAILTAIL | awk '{ print $1 }')

    if [[ $NEWMAIL -gt 0 ]]
    then 
        UNSEENMAIL=$(echo $MAILTAIL | awk '{ print $6 }')

        TOTALMAIL=$(($NEWMAIL + $UNSEENMAIL))

        declare -r MAILMSG="[ $NEWMAIL / $TOTALMAIL ]"

        $NOTIFY_CMD "NEW MAIL $MAILMSG"
        
        if [[ -n $2 ]]
        then
            playsound "$2" > /dev/null &
        fi
    fi
}

# Print progress bar
printProgress() {
    declare -r BACKSPACE=""
    declare -ir WIDTH=39
    declare -ir FACTOR=$(($WIDTH - 2))
    declare -i columns=0
    declare -i n=$(($WIDTH + 1))

    stepsize=$(echo "scale=2; $1/$FACTOR" | bc -q)

    while [[ $n -gt 0 ]]
    do
        print $BACKSPACE $(($WIDTH + 6 + ${#2} + ${#3}))

        print "  [" 1
        print "=" $columns
        print " " $(($WIDTH - $columns))
        print "] $2$3 " 1

        ((columns++))
        ((n--))

        sleep $stepsize
    done
}

#loop until user break or run timeout
program() {
    declare -i runcount=1
    declare -i n=$2
    declare runDescription=""
    declare output=""

    if [[ $n -gt 0 ]]
    then
        runDescription="/$n"
    fi


    while [[ $n -ne 0 ]] 
    do
        if [[ $7 == false ]]
        then
            echo "mailcheck - $4 $5 interval"    
        
            output=$(getmail -$6 | tail -qn +3)
            echo "$output"


            if [[ $8 == true || -n $9 ]]
            then
                processNotify "$output" "$9"
            fi

        
            if [[ $3 == true ]] 
            then
                sleep $1
            else
                printProgress $1 "$runcount" $runDescription
            fi

            clear                        

        else
            sleep $1

            output=$(getmail -$6 | tail -qn +3)
        
            if [[ $8 == true || -n $9 ]]
            then
                processNotify "$output" "$9"
            fi
        fi
        
        ((runcount++))    

        ((n--))
    done

    exit 0
}

# print help
printHelp() {
    echo "NAME"
    echo "     mailcheck - An automated mail checker for getmail"
    echo

    echo "SYNTAX"
    echo "     mailcheck [-dhmqQv] [-a <arg>] [-s <delay(s)>] [-m <delay(m)>] [-n <runs>] [-p <audiofile>]"
    echo

    echo "VERSION"
    echo "     version $VERSION"
    echo

    echo "OPTIONS"
    echo "    -a"
    echo "     specify arguments for getmail(default -ln)"
    echo
    echo "    -d"
    echo "     default delay(set on default) of 60 seconds"
    echo
    echo "    -f"
    echo "     use notify daemon to notify on new mail"
    echo
    echo "    -p"
    echo "     use audio file to notify on new mail"
    echo
    echo "    -h"
    echo "     print this help and exit"
    echo
    echo "    -m"
    echo "     delay in minutes"
    echo
    echo "    -n"
    echo "     number of runs(default set to loop)"
    echo
       echo "    -q"
    echo "     quiet countdown"
    echo
       echo "    -Q"
    echo "     stealth mode to suppress all further output"
    echo
    echo "    -s"
    echo "     delay in seconds"
    echo
    echo "    -v"
    echo "     print version and exit"
    echo


    echo "AUTHOR"
    echo "    Xander Wilcke"
    echo "    wex.wilcke@student.vu.nl"
    echo "    https://www.few.vu.nl/~wwe300/scripts.html"
    echo 
}

# arguments handler
arguments() {
    # -a : getmail arguments
    # -d : default delay
    # -f : use notify
    # -p : use music
    # -q : silent
    # -Q : stealth
    # -s : read seconds
    # -m : read minutes
    # -n : number of runs
    # -h : display help
    # -v : display version
    declare -i delay=DEFAULT_DELAY
    declare -i runs=DEFAULT_NR_OF_RUNS
    declare args="nl"
    declare mfile=""
    declare description="$delay seconds"
    declare silent=false
    declare stealth=false
    declare notify=false

    checkInRange $@

    while getopts ":dfqhQva:m:s:n:p:" optname
    do
        case "$optname" in
            "d")
                description="$delay second"
                ;;
            "s")
                delay=$OPTARG
                
                description="$OPTARG second"
                ;;
            "m")
                declare -ir minToSec=60

                delay=$(($OPTARG*minToSec))

                description="$OPTARG minute"
                ;;
            "a")
                args=$OPTARG
                ;;
            "n")
                runs=$OPTARG
                ;;
            "p")
                mfile=$OPTARG
                ;;
            "f")
                notify=true
                ;;
            "q")
                silent=true
                ;;
            "Q")
                silent=true
                stealth=true
                ;;
            "h")
                printHelp

                exit 0
                ;;
            "v")
                echo mailcheck $VERSION

                exit 0
                ;;
            "?")
                echo "Option unknown: $OPTARG"
                echo "Use -h to print help"

                exit 1
                ;;
            ":")
                echo "Option $OPTARG requires an argument"
                echo "Use -h to print help"

                exit 1
                ;;
            *)            
                echo "Unknown Error"
                echo "Use -h to print help"

                exit 1
                ;;
        esac
    done
    program $delay $runs $silent $description $args $stealth $notify $mfile
}

# check if input is in range
checkInRange() {
    for i in $@
    do
        if [[ $(echo $i | grep -E "^(\+|-)?[0-9]+$") && $i -lt 1 ]]
        then
            echo "INPUT ERROR :: argument < 1"

            exit 1
        fi
    done
}


# print character a given number of times
print() {
    for((i=1; i<=$2; i++)) 
    do
        echo -ne "${1}"
    done
}

# check if all required programs are installed
checkRequired() {
    if [[ ! -x /usr/bin/getmail ]]
    then
        echo "ERROR :: getmail is required but can not be located"

        exit 1
    elif [[ ! -x /usr/bin/bc ]]
    then
        echo "ERROR :: bc is required but can not be located"

        exit 1
    elif [[ ! -x /usr/bin/notify-send ]]
    then
        echo "NOTE :: notify-send is required for OSD notification(-f) but can not be located"
    elif [[ ! -x /usr/bin/playsound ]]
    then
        echo "NOTE :: playsound is required for audio notification(-p) but can not be located"
    fi
}


# init
checkRequired

if [[ -z $1 ]]    #if no argument is given
then
    arguments -d    # default
else
    arguments $@
fi


# ============
# End of File
# ============

Download(.sh)

Tips and bug reports are welcomed tongue

Offline

#1482 2011-07-02 23:58:10

GraveyardPC
Member
Registered: 2008-11-29
Posts: 99

Re: Post your handy self made command line utilities

A prettier nmap:
http://dl.dropbox.com/u/519931/scan.png

#!/bin/bash

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

hosts=( $(nmap -F -P0 "${1}" | awk '/report for/ { printf "%s ", $5 }') )

for host in ${hosts[@]}; do
  
  scan=$(nmap -sS -sV -A -T4 -P0 "${host}")
  
  mac=$(cat /proc/net/arp | awk '$1 ~ /^'"${host}"'$/ { print $4 }')
  os=$(echo "${scan}" | awk '/OS details:/ { $1 = $2 = ""; printf substr($0, 3, 100) }')
  device=$(echo "${scan}" | awk '/Service Info: Device:/ { $1 = $2 = $3 = ""; print substr($0, 4) }')
  fallback=$(echo "${os}" | awk '{ print $1 }')
  box="${fallback:-Unknown} Box"
  
  printf "\n%8s: \033[1;31m%s\033[0m\n" "Device" "${device:-$box}"
  printf "%8s: \033[1;33m%s\033[0m\n" "IPv4" "${host}"
  printf "%8s: %s\n" "MAC" "${mac:-Unknwon}"
  printf "%8s: %s\n" "OS" "${os:-Unknown}"
  
  echo "${scan}" | awk '
  $2 ~ /^open$/ {
    p = $1;
    $1 = $2 = "";
    printf "\n\033[1;32m%7s>> %s\033[0m\n%7s\033[1;32m + \033[1;37m%s\033[0m\n",
           "", p, "", substr($0, 3, 100)
  }
  $1 ~ /\|_/ {
    printf "%7s \033[0;32m-\033[0m %s\n", "", substr($0, 3, 100)
    last = 1;
  }'
  
done
echo

Last edited by GraveyardPC (2011-07-03 00:23:05)

Offline

#1483 2011-07-16 21:08:23

examon
Member
Registered: 2011-05-07
Posts: 208

Re: Post your handy self made command line utilities

I was searching for cli google translator.
Some days ago I found one line of code, which is very useful for me.

#!/bin/bash
wget -qO- "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=$1&langpair=$2|${3:-sk}" | sed 's/.*"translatedText":"\([^"]*\)".*}/\1\n/';

In action:

$ hello
ahoj
$ bonjour
ahoj

Source language is autodetected and translated into Slovak language.
If you want to change target language, just change 'sk' in code.

Sentences:

$ "we love linux"
milujeme linux

Rotated:

$ "mam rad linux" sk en
I like linux

Offline

#1484 2011-07-18 00:53:45

zcid
Member
Registered: 2011-03-26
Posts: 6

Re: Post your handy self made command line utilities

runrar is a basic unrar wrapper designed for batch unraring files in multiple directories (think entire or multiple seasons of tv). It isn't very elegant but it has been serving me quite well for a while.

Let's say you have a directory heirarchy such as:

main_dir-|
         |
         |-sub_dir1
         |
         |-sub_dir2
         |
         |-sub_dir3

Each sub-directory contains a rar archive. And in theory this script will descend as many directory levels as necessary during its search.

runrar by itself will unrar each archive and leave the files in their respective directories.

The '-s' flag allows you to pass a directory in which to save the extracted files.
The '-c' flag verifies the files via any sfv files found.

For instance: I usually use the command line 'unrar -c -s ./' which will extract all archives in child directories and save the files to the current directory after performing md5 checks.

Requires unrar to be installed.

Offline

#1485 2011-07-20 04:52:49

woddfellow2
Member
From: USA
Registered: 2010-04-05
Posts: 113
Website

Re: Post your handy self made command line utilities

Weather script (warning: US/National Weather Service–centric, preconfigured for Tulsa, OK):

#!/bin/sh

# This is a simple script that downloads current weather conditions and zone
# forecast from the National Weather Service to /tmp and displays them.
# 
# This script is preconfigured for the Tulsa, OK area.
# It is biased toward the US, as it gets its data from the NWS.
# 
# To change the observations site, replace KTUL with another observations site.
# See <http://weather.noaa.gov/pub/data/observations/metar/decoded/> for a list.
# For the bare, unparsed METAR, replace "decoded" in the URI with "stations".
# 
# To change the forecast zone, replace ok/okz060 with another forecast zone.
# See <http://weather.noaa.gov/pub/data/forecasts/zone/> for a list.

wget -q -O /tmp/wx-current.txt http://weather.noaa.gov/pub/data/observations/metar/decoded/KTUL.TXT
echo "********** CURRENT CONDITIONS **********"
cat /tmp/wx-current.txt
echo
echo "********** NWS ZONE FORECAST **********"
wget -q -O /tmp/wx-forecast.txt http://weather.noaa.gov/pub/data/forecasts/zone/ok/okz060.txt
cat /tmp/wx-forecast.txt

...and a simpler script that gets a weather radar image and then uses feh to display it:

#!/bin/sh
wget -O /tmp/wx-radar.png http://radar.weather.gov/ridge/lite/N0R/INX_0.png
feh /tmp/wx-radar.png

I have the first script aliased to "wx", which runs the script and pipes it through less. The radar script is aliased to "wx-radar".


1-Crawl 2-Cnfg 3-ATF 4-Exit ?

Offline

#1486 2011-07-20 04:59:51

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

Re: Post your handy self made command line utilities

@woddfellow2, you don't want any of the temporary files.
wget can output to stdout:

wget -q -O- http://weather.noaa.gov/pub/data/observations/metar/decoded/KTUL.TXT

feh is compiled with libcurl support, so you can just:

feh http://radar.weather.gov/ridge/lite/N0R/INX_0.png

Well, in reality, feh creates a tmporary file in /tmp too, and removes it on quit.

Last edited by lolilolicon (2011-07-20 05:04:23)


This silver ladybug at line 28...

Offline

#1487 2011-07-20 05:12:20

woddfellow2
Member
From: USA
Registered: 2010-04-05
Posts: 113
Website

Re: Post your handy self made command line utilities

Er, thanks...

Revised versions:

weather.sh:

#!/bin/sh

# This is a simple script that downloads current weather conditions and zone
# forecast from the National Weather Service and displays them.
# 
# This script is preconfigured for the Tulsa, OK area.
# It is biased toward the US, as it gets its data from the NWS.
# 
# To change the observations site, replace KTUL with another observations site.
# See <http://weather.noaa.gov/pub/data/observations/metar/decoded/> for a list.
# For the bare, unparsed METAR, replace "decoded" in the URI with "stations".
# 
# To change the forecast zone, replace ok/okz060 with another forecast zone.
# See <http://weather.noaa.gov/pub/data/forecasts/zone/> for a list.

echo "********** CURRENT CONDITIONS **********"
wget -q -O- http://weather.noaa.gov/pub/data/observations/metar/decoded/KTUL.TXT
echo
echo "********** NWS ZONE FORECAST **********"
wget -q -O- http://weather.noaa.gov/pub/data/forecasts/zone/ok/okz060.txt

wx-radar.sh:

#!/bin/sh
feh http://radar.weather.gov/ridge/lite/N0R/INX_0.png

[2011-07-20T00:15-0500] Update: Changed comment in weather.sh to remove mention of /tmp

Last edited by woddfellow2 (2011-07-20 05:15:17)


1-Crawl 2-Cnfg 3-ATF 4-Exit ?

Offline

#1488 2011-07-20 16:15:10

egan
Member
From: Mountain View, CA
Registered: 2009-08-17
Posts: 273

Re: Post your handy self made command line utilities

Here's a similar program for use with the Google API. It's programmed for Mountain+View by default, but that can be changed either by editing the variable, or by passing a different argument (city or zip code). It'll get either current conditions or a forecast; I have aliases to each invocation so I can say "forecast London" or "weather 10001".

#!/bin/bash

##
# gweather	-- obtain weather data using google api
#
# usage		-- gweather [-c|--current]|[-f|--forecast][LOCID]
#			-LOCID can be given as a string or zip code
#			-When unspecified, LOCID=$locid
#
# notes		-- designed for use from aliases
#
# written	-- 12 September, 2010 by Egan McComb
#
# revised	--
##

current="$HOME/bin/.current.xslt"
forecast="$HOME/bin/.forecast.xslt"
locid="Mountain+View" #"95616"

usage()
{
	echo "Usage: $(basename $0) [-c|--current]|[-f|--forecast] [LOCID]" >&2
	echo -e "\t-LOCID can be given as a string or zip code" >&2
	echo -e "\t-When unspecified, LOCID=$locid" >&2
}

convert()
{
	iconv -f ISO-8859-1 -t UTF-8
}

check()
{
	read -d "" reply
	if (( $(grep -c "$" <<< "$reply") == 1 ))
	then
		echo "Error: Invalid LOCID '$locid'" >&2
		exit 1
	else
		echo "$reply"
	fi
}

chkargs()
{
	if (( ! $# ))
	then
		echo "Error: Too few arguments" >&2
		usage
		exit $ERR_NARGS
	elif [[ $1 = "-f" ]] || [[ $1 = "--forecast" ]]
	then
		filter=$forecast
	elif [[ $1 = "-c" ]] || [[ $1 = "--current" ]]
	then
		filter=$current
	elif (( $# > 1 ))
	then
		echo "Error: Too many arguments" >&2
		usage
		exit $ERR_NARGS
	else
		echo "Error: Invalid arguments" >&2
		usage
		exit $ERR_VARGS
	fi
	if [[ ! -z "$2" ]]
	then
		locid="$2"
	fi
}

##----MAIN---##
chkargs "$@"
qurl="http://www.google.com/ig/api?weather=$locid"
curl -s "$qurl" | convert | xsltproc $filter - | check

The program requires these xslt files to function:

<!-- XSLT to translate XML reponse from www.google.com/ig/ XML weather API.
     Extracts current conditions data. -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" > 
    <xsl:output method="text" disable-output-escaping="yes"/>
    <xsl:template match="xml_api_reply">
        <xsl:apply-templates select="problem_cause"/>
        <xsl:apply-templates select="weather"/>
    </xsl:template>

    <xsl:template match="weather">
        <xsl:variable name="newline"><xsl:text>&#10;</xsl:text></xsl:variable>
        <xsl:text>Location: </xsl:text><xsl:value-of select ="forecast_information/city/@data"/>
        <xsl:value-of select="$newline" />
        <xsl:text>Temperature: </xsl:text><xsl:value-of select="current_conditions/temp_c/@data"/> <xsl:text>°C</xsl:text>
        <xsl:text> (</xsl:text><xsl:value-of select="current_conditions/temp_f/@data"/><xsl:text>°F)</xsl:text>
        <xsl:value-of select="$newline"/>
        <xsl:text>Conditions: </xsl:text><xsl:value-of select="current_conditions/condition/@data"/>
        <xsl:value-of select="$newline"/>
        <xsl:value-of select="current_conditions/humidity/@data"/>
        <xsl:value-of select="$newline"/>
        <xsl:value-of select="current_conditions/wind_condition/@data"/>
        <xsl:value-of select="$newline"/>
    </xsl:template>
</xsl:stylesheet>
<!-- XSLT to translate XML reponse from www.google.com/ig/ XML weather API.
     Extracts forecast data. -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" > 
    <xsl:output method="text" disable-output-escaping="yes"/>
    <xsl:template match="xml_api_reply">
        <xsl:apply-templates select="weather"/>
    </xsl:template>
    
    <xsl:template match="weather">
        <xsl:variable name="unit_system" select="forecast_information/unit_system/@data"/>
        <xsl:variable name="newline"><xsl:text>&#10;</xsl:text></xsl:variable>
        <xsl:text>Location: </xsl:text><xsl:value-of select="forecast_information/city/@data"/>
        
        <xsl:for-each select="forecast_conditions">
            <xsl:value-of select="$newline"/>
            <xsl:value-of select="day_of_week/@data"/><xsl:text>: </xsl:text>
            <xsl:value-of select="$newline"/>
            <xsl:choose>
                <xsl:when test="$unit_system != 'SI'">
                    <xsl:text>    Conditions: </xsl:text>
                    <xsl:value-of select="condition/@data"/>
                    <xsl:value-of select="$newline"/>
                    <xsl:text>    Temperature: </xsl:text>
                    <xsl:value-of select="round(((number(low/@data)-32)*5)div9)"/><xsl:text>°C</xsl:text>
                    <xsl:text> (</xsl:text><xsl:value-of select="low/@data"/><xsl:text>°F)</xsl:text>
                    <xsl:value-of select="$newline"/>
                    <xsl:text>                 </xsl:text>
                    <xsl:value-of select="round(((number(high/@data)-32)*5)div9)"/><xsl:text>°C</xsl:text>
                    <xsl:text> (</xsl:text><xsl:value-of select="high/@data"/><xsl:text>°F)</xsl:text>
                    
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>    Conditions: </xsl:text>
                    <xsl:value-of select="condition/@data"/>
                    <xsl:value-of select="$newline"/>
                    <xsl:text>    Temperature: </xsl:text>
                    <xsl:value-of select="low/@data"/><xsl:text>°C</xsl:text>
                    <xsl:text> (</xsl:text><xsl:value-of select="round(((number(low/@data)*9)div5)+32)"/><xsl:text>°F)</xsl:text>
                    <xsl:value-of select="$newline"/>
                    <xsl:text>                 </xsl:text>
                    <xsl:value-of select="high/@data"/><xsl:text>°C</xsl:text>
                    <xsl:text> (</xsl:text><xsl:value-of select="round(((number(high/@data)*9)div5)+32)"/><xsl:text>°F)</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
        <xsl:value-of select="$newline"/>
    </xsl:template>
</xsl:stylesheet>

Last edited by egan (2012-01-05 23:46:49)

Offline

#1489 2011-07-21 03:18:31

tomd123
Developer
Registered: 2008-08-12
Posts: 565

Re: Post your handy self made command line utilities

Been a while since I posted here, but here are some noteworthy scripts imo:

I like to keep a folder of upstream repositories and the following is a quick way to update all of those project repos.
There are missing repo types, but this is what I need so far tongue adjust to your needs.

#!/bin/bash

for i in */
do
  # used to remove trailing /, is there a cleaner way of doing this?
  i=${i%/}
  cd $i
    [[ -d .bzr ]] && echo "=== updating $i in bzr ===" && bzr update
    [[ -d .git ]] && echo "=== updating $i in git ===" && git pull
    [[ -d .svn ]] && echo "=== updating $i in svn ===" && svn up
    [[ -d .hg  ]] && echo "=== updating $i in hg ==="  && hg pull -u
  cd ..
done

Another script that I've created is an abs equivalent tool for the aur git repo located at http://pkgbuild.com/git/aur.git/
It stores a git repo of the aur into /var/aur (like /var/abs for abs)

#!/bin/bash

if [[ -d /var/aur ]]
then
  cd /var/aur
  git pull
else
  cd /var
  git clone git://pkgbuild.com/aur.git
fi

Offline

#1490 2011-07-22 07:49:04

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: Post your handy self made command line utilities

A kludge based on absent. It checks the version of the ABS PKGBUILD against that in the repos and, if it doesn't match. offers to upgrade using absent. There is a switch to sync the ABS package beforehand.

#!/bin/bash
# Check currency of ABS packages
# Snippet lifted from absent: http://aur.archlinux.org/packages.php?ID=50669
# add /usr/bin/abs to sudoers if you don't want the password prompt

mag=$'\e[1;35m'   # magenta
yel=$'\e[1;33m'   # yellow
grn=$'\e[1;32m'   # green
red=$'\e[1;31m'
ec=$'\e[0m'       # end colour
searchdirs=("/var/abs/core" "/var/abs/extra" "/var/abs/community")

for name in "$@"; do
    for repo in "${searchdirs[@]}"; do
        if [[ -d ${repo}/${name} && -f ${repo}/${name}/PKGBUILD ]]; then
        
        # synchronize repo 
        case "$1" in
        -s | -sync) sudo abs ${repo}/${name}  ;;
        *) : ;;
        esac

        # print the current version details
        avers="$(awk -F= '/^pkgv|^pkgr/{s=s (s?"-":"") $2} END {printf "%s", s}'\
          <${repo}/${name}/PKGBUILD)"
        pvers="$(awk '/Version/ {print $3}' <(pacman -Si ${name}))"
        echo "${mag}ABS version${ec}" 
        echo "$avers"
        echo "${yel}${repo##*/} version${ec}"
        echo "$pvers"

          # upgrade with absent?
          if [[ "$avers" != "$pvers" ]]; then
            while true; do
            read -p "${grn}Do you want to upgrade to ${red}$pvers?${ec} [y/n] " yn
            case $yn in
            [yY]*) absent ${name}; break ;;
            [nN]*) exit;;
            *) echo "[y]es or [n]o?" ;;
            esac
            done
          fi
        fi
    done
done 

I can't quite believe that it actually seems to work (with the limited testing I have done)...


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#1491 2011-07-31 18:43:35

Fackamato
Member
Registered: 2006-03-31
Posts: 579

Re: Post your handy self made command line utilities

Here's a script I use to check the status/health of my harddrives and the RAID6 MD array on my HTPC. Ironically enough, /dev/sdh failed today. Luckily I'm on RAID6. Good thing I migrated from RAID5 a while ago!

#!/bin/bash
# by fackamato @ Arch BBS
LOGFILE="/srv/http/logs/smartctl-weekly.log"
[[ -e "$LOGFILE" ]] && rm -f $LOGFILE
echo -e "DEV\tEVENTS\tREALL\tPEND\tUNCORR\tCRC\tRAW\tZONE\tEND" >> $LOGFILE
for I in /dev/sd{b,c,d,e,f,g,h}; do
        unset DEV; unset EVENTS; unset REALL; unset PEND; unset UNCORR; unset CRC; unset RAW; unset ZONE; unset END; unset MDDEV
        DEVTEMP=`echo $I | awk -F'/' '{print $3}'`
        #SMARTTEMP="/tmp/smarttmp.txt"
        SMARTTEMP="/srv/http/logs/smart-"$DEVTEMP".txt"
        [[ -e "$SMARTTEMP" ]] && rm -f $SMARTTEMP
        smartctl -a $I > $SMARTTEMP
        MDDEV=$I"1"
        DEV=`echo $MDDEV | awk -F'/' '{print $3}'`
        EVENTS=`mdadm -E $MDDEV | grep Events | awk '{print $3}'`
        unset LINE; while read LINE; do
                if [ -n "$LINE" ]; then
                        case "$LINE" in
                                # *"/dev/sd"* ) DEV=$LINE ;;
                                *"5 Reallocated_Sector_Ct"* ) REALL=`echo $LINE | awk '{print $10}'` ;;
                                *"197 Current_Pending_Sector"* ) PEND=`echo $LINE | awk '{print $10}'` ;;
                                *"198 Offline_Uncorrectable"* ) UNCORR=`echo $LINE | awk '{print $10}'` ;;
                                *"199 UDMA_CRC_Error_Count"* ) CRC=`echo $LINE | awk '{print $10}'` ;;
                                *"End"* )  END=`echo $LINE | awk '{print $10}'` ;;
                                *"1 Raw_Read_Error_Rate"* ) RAW=`echo $LINE | awk '{print $10}'` ;;
                                *"200 Multi_Zone_Error_Rate"* ) ZONE=`echo $LINE | awk '{print $10}'` ;;
                        esac
                fi
        done < $SMARTTEMP
        echo -e "$DEV\t$EVENTS\t$REALL\t$PEND\t$UNCORR\t$CRC\t$RAW\t$ZONE\t$END" >> $LOGFILE
done
echo -e "\n" >> $LOGFILE
cat /proc/mdstat >> $LOGFILE
echo -e "\n" >> $LOGFILE
mdadm -D /dev/md0 >> $LOGFILE

Sample output:

DEV    EVENTS    REALL    PEND    UNCORR    CRC    RAW    ZONE    END
sdb1    6158767    0    0    0    2    0    0    
sdc1    6158767    0    0    0    0    0    0    
sdd1    6158767    0    0    0    0    0    0    
sde1    6158768    0    0    0    0    0    1    
sdf1    6158767    0    0    0    0    47    6    
sdg1    6158767    0    0    0    0    0    0    
sdh1    6158767    0    7    1    0    340    3    


Personalities : [raid6] [raid5] [raid4] 
md0 : active raid6 sdh1[6] sdg1[0] sdf1[5] sde1[7] sdd1[4] sdb1[1] sdc1[3]
      9751756800 blocks super 1.2 level 6, 64k chunk, algorithm 2 [7/7] [UUUUUUU]
      
unused devices: <none>


/dev/md0:
        Version : 1.2
  Creation Time : Tue Oct 19 08:58:41 2010
     Raid Level : raid6
     Array Size : 9751756800 (9300.00 GiB 9985.80 GB)
  Used Dev Size : 1950351360 (1860.00 GiB 1997.16 GB)
   Raid Devices : 7
  Total Devices : 7
    Persistence : Superblock is persistent

    Update Time : Sun Jul 31 16:29:42 2011
          State : clean
 Active Devices : 7
Working Devices : 7
 Failed Devices : 0
  Spare Devices : 0

         Layout : left-symmetric
     Chunk Size : 64K

           Name : ion:0  (local to host ion)
           UUID : e6595c64:b3ae90b3:f01133ac:3f402d20
         Events : 6158767

    Number   Major   Minor   RaidDevice State
       0       8       97        0      active sync   /dev/sdg1
       1       8       17        1      active sync   /dev/sdb1
       4       8       49        2      active sync   /dev/sdd1
       3       8       33        3      active sync   /dev/sdc1
       5       8       81        4      active sync   /dev/sdf1
       6       8      113        5      active sync   /dev/sdh1
       7       8       65        6      active sync   /dev/sde1

(yes, I seem to have a dying harddrive sad, it's not even a year old)

Here's one that I stole from Ubuntuforums, source here: http://ubuntuforums.org/showthread.php?p=11105298
I modified the script somewhat. It's attempting to tune the performance of a RAID5/6 array on MD. (I'm CPU limited so can't test if this works or not)

#!/bin/bash
###############################################################################
#  simple script to set some parameters to increase performance on a mdadm
# raid5 or raid6. Ajust the ## parameters ##-section to your system!
#
#  WARNING: depending on stripesize and the number of devices the array might
# use QUITE a lot of memory after optimization!
#
#  27may2010 by Alexander Peganz
#  31jul211 modified by Mathias B
###############################################################################


## parameters ##
MDDEV=md0               # e.g. md51 for /dev/md51
CHUNKSIZE=64            # in KB
BLOCKSIZE=4             # of file system in KB
NCQ=enable              # disable, enable. ath. else keeps current setting
NCQDEPTH=31             # 31 should work for almost anyone
FORCECHUNKSIZE=true     # force max sectors kb to chunk size > 512
DOTUNEFS=true           # run tune2fs, ONLY SET TO true IF YOU USE EXT[34]
RAIDLEVEL=raid6         # raid5, raid6


## code ##
# test for priviledges
if [ "$(whoami)" != 'root' ]; then
        echo $(date): Need to be root >> /#tuneraid.log
        exit 1
fi

# set number of parity devices
NUMPARITY=1
[[ $RAIDLEVEL == "raid6" ]] && NUMPARITY=2
echo "Using $NUMPARITY parity devices ($RAIDLEVEL)"
# get all devices
DEVSTR="`grep \"^$MDDEV : \" /proc/mdstat` eol"
while \
 [ -z "`expr match \"$DEVSTR\" '\(\<sd[a-z]1\[[12]\?[0-9]\]\((S)\)\? \)'`" ]
do
        DEVSTR="`echo $DEVSTR|cut -f 2- -d \ `"
done

# get active devices list and spares list
DEVS=""
SPAREDEVS=""
while [ "$DEVSTR" != "eol" ]; do
        CURDEV="`echo $DEVSTR|cut -f -1 -d \ `"
        if [ -n "`expr match \"$CURDEV\" '\(\<sd[a-z]1\[[12]\?[0-9]\]\((S)\)\)'`" ]; then
                SPAREDEVS="$SPAREDEVS${CURDEV:2:1}"
        elif [ -n "`expr match \"$CURDEV\" '\(\<sd[a-z]1\[[12]\?[0-9]\]\)'`" ]; then
                DEVS="$DEVS${CURDEV:2:1}"
        fi
        DEVSTR="`echo $DEVSTR|cut -f 2- -d \ `"
done

NUMDEVS=${#DEVS}
NUMSPAREDEVS=${#SPAREDEVS}

# test if number of devices makes sense
if [ ${#DEVS} -lt $[1+$NUMPARITY] ]; then
        echo $(date): Need more devices >> /#tuneraid.log
        exit 1
fi

echo "Found $NUMDEVS devices with $NUMSPAREDEVS spares"

# set read ahead
RASIZE=$[$NUMDEVS*($NUMDEVS-$NUMPARITY)*2*$CHUNKSIZE]   # in 512b blocks
echo read ahead size per device: $RASIZE blocks \($[$RASIZE/2]kb\)
MDRASIZE=$[$RASIZE*$NUMDEVS]
echo read ahead size of array: $MDRASIZE blocks \($[$MDRASIZE/2]kb\)
blockdev --setra $RASIZE /dev/sd[$DEVS]
#blockdev --setra $RASIZE /dev/sd[$SPAREDEVS]
blockdev --setra $MDRASIZE /dev/$MDDEV

# set stripe cache size
STRCACHESIZE=$[$RASIZE/8]                               # in pages per device
echo stripe cache size of devices: $STRCACHESIZE pages \($[$STRCACHESIZE*4]kb\)
echo $STRCACHESIZE > /sys/block/$MDDEV/md/stripe_cache_size

# set max sectors kb
DEVINDEX=0
MINMAXHWSECKB=$(cat /sys/block/sd${DEVS:0:1}/queue/max_hw_sectors_kb)
until [ $DEVINDEX -ge $NUMDEVS ]; do
        DEVLETTER=${DEVS:$DEVINDEX:1}
        MAXHWSECKB=$(cat /sys/block/sd$DEVLETTER/queue/max_hw_sectors_kb)
        if [ $MAXHWSECKB -lt $MINMAXHWSECKB ]; then
                MINMAXHWSECKB=$MAXHWSECKB
        fi
        DEVINDEX=$[$DEVINDEX+1]
done
if [ $CHUNKSIZE -le $MINMAXHWSECKB ] && ( [ $CHUNKSIZE -le 512 ] || [[ $FORCECHUNKSIZE == "true" ]] ); then
        echo Setting max sectors KB to match chunk size
        DEVINDEX=0
        until [ $DEVINDEX -ge $NUMDEVS ]; do
                DEVLETTER=${DEVS:$DEVINDEX:1}
                echo "Set max sectors KB to $CHUNKSIZE on $DEVLETTER"
                echo $CHUNKSIZE > /sys/block/sd$DEVLETTER/queue/max_sectors_kb
                DEVINDEX=$[$DEVINDEX+1]
        done
        DEVINDEX=0
        until [ $DEVINDEX -ge $NUMSPAREDEVS ]; do
                DEVLETTER=${SPAREDEVS:$DEVINDEX:1}
                echo "Set max sectors KB to $CHUNKSIZE on $DEVLETTER"
                echo $CHUNKSIZE > /sys/block/sd$DEVLETTER/queue/max_sectors_kb
                DEVINDEX=$[$DEVINDEX+1]
        done
fi

# enable/disable NCQ
DEVINDEX=0
if [[ $NCQ == "enable" ]] || [[ $NCQ == "disable" ]]; then
        if [[ $NCQ == "disable" ]]; then
                NCQDEPTH=1
        fi
        until [ $DEVINDEX -ge $NUMDEVS ]; do
                DEVLETTER=${DEVS:$DEVINDEX:1}
                echo Setting NCQ queue depth to $NCQDEPTH on $DEVLETTER
                echo $NCQDEPTH > /sys/block/sd$DEVLETTER/device/queue_depth
                DEVINDEX=$[$DEVINDEX+1]
        done
        DEVINDEX=0
        until [ $DEVINDEX -ge $NUMSPAREDEVS ]; do
                DEVLETTER=${SPAREDEVS:$DEVINDEX:1}
                echo Setting NCQ queue depth to $NCQDEPTH on $DEVLETTER
                echo $NCQDEPTH > /sys/block/sd$DEVLETTER/device/queue_depth
                DEVINDEX=$[$DEVINDEX+1]
        done
fi

# tune2fs
if [[ $DOTUNEFS == "true" ]]; then
        STRIDE=$[$CHUNKSIZE/$BLOCKSIZE]
        STRWIDTH=$[$CHUNKSIZE/$BLOCKSIZE*($NUMDEVS-$NUMPARITY)]
        echo setting stride to $STRIDE blocks \($CHUNKSIZE KB\)
        echo setting stripe-width to $STRWIDTH blocks \($[$STRWIDTH*$BLOCKSIZE] KB\)
        echo tune2fs -E stride=$STRIDE,stripe-width=$STRWIDTH /dev/$MDDEV
fi

# exit
echo $(date): Success >> /#tuneraid.log
exit 0

Offline

#1492 2011-07-31 20:15:57

juster
Forum Fellow
Registered: 2008-10-07
Posts: 195

Re: Post your handy self made command line utilities

Fackamato, I like the idea of your smartctl script but the style bugs me. You are basically re-implementing awk with bash's case when it is easier to just let awk do it for you. You can also wrap everything in a function and redirect the function instead of redirecting every output to the logfile. Or just have all the printing done in a script which you redirect to the logfile on the shell.

#!/bin/bash

barf() {
    echo -e "DEV\tEVENTS\tREALL\tPEND\tUNCORR\tCRC\tRAW\tZONE\n"
    for I in sd{b,c,d,e,f,g,h} ; do
        EVENTS=$(mdadm -E $MDDEV | awk '/Events/ {print $3}')
        smartctl -a "/dev/$I" | awk -v dev="$I" -v events="$EVENTS" '
$1 == 1 { raw = $10 }
$1 == 5 { reall = $10 }
$1 == 197 { pend = $10 }
$1 == 198 { uncorr = $10 }
$1 == 199 { crc = $10 }
$1 == 200 { zone = $10 }
END { print dev, events, reall, pend, uncorr, crc, raw, zone }
'
    done

    echo
    cat /proc/mdstat
    echo
    mdadm -D /dev/md0
}

barf > "/srv/http/logs/smartctl-weekly.log"

This is untested but I hope you get the idea. You could also match names inside awk (see the first awk with /Events/) but i figured I would use the provided numbers.

Offline

#1493 2011-07-31 20:27:21

Fackamato
Member
Registered: 2006-03-31
Posts: 579

Re: Post your handy self made command line utilities

juster wrote:

Fackamato, I like the idea of your smartctl script but the style bugs me. You are basically re-implementing awk with bash's case when it is easier to just let awk do it for you. You can also wrap everything in a function and redirect the function instead of redirecting every output to the logfile. Or just have all the printing done in a script which you redirect to the logfile on the shell.

#!/bin/bash

barf() {
    echo -e "DEV\tEVENTS\tREALL\tPEND\tUNCORR\tCRC\tRAW\tZONE\n"
    for I in sd{b,c,d,e,f,g,h} ; do
        EVENTS=$(mdadm -E $MDDEV | awk '/Events/ {print $3}')
        smartctl -a "/dev/$I" | awk -v dev="$I" -v events="$EVENTS" '
$1 == 1 { raw = $10 }
$1 == 5 { reall = $10 }
$1 == 197 { pend = $10 }
$1 == 198 { uncorr = $10 }
$1 == 199 { crc = $10 }
$1 == 200 { zone = $10 }
END { print dev, events, reall, pend, uncorr, crc, raw, zone }
'
    done

    echo
    cat /proc/mdstat
    echo
    mdadm -D /dev/md0
}

barf > "/srv/http/logs/smartctl-weekly.log"

This is untested but I hope you get the idea. You could also match names inside awk (see the first awk with /Events/) but i figured I would use the provided numbers.


I'm an awk newbie, so thanks, I'll check it out.

Offline

#1494 2011-08-01 15:10:29

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: Post your handy self made command line utilities

I wrote a function for drawing backgrounds behind text supplied on stdin.

I use it with a system monitor script to draw the Japanese day name kanji.
Here is a screenshot:
http://ompldr.org/vOXBwdQ

Here is the code with example kanji (11x13 to 15, offset to the right at bit)
The array is called kanjiday and it's used only once in the function.
The index is called DAYNR and in this case is updated somewhere else with date +%w.
The background color is blue and comes from \x1b[44m that appears once.
You can use any characters to draw the figures and they can be any size.
Usage is: command | kanji_background

function kanji_background() {
    local search match line color mark counter ln=1 total=
    IFS=$'\n'
    for line in $( echo "${kanjiday[$DAYNR]}" | while read -n 1; do
                if [[ $old != $REPLY ]]; then
                    if [[ $old == '' ]]; then
                        echo
                        counter=-1
                    else
                        ((counter!=0))
                        echo -n $counter\ 
                    fi
                    counter=0
                fi
                ((++counter))
                old=$REPLY
            done | tail -n +2); do
        IFS=' '
        search="$((ln++)){s/"
        match=
        mark=no
        counter=1
        for color in $line; do
            search+='\(.\{'$color'\}\)'
            [[ $mark = no ]] && {
                match+='\'$((counter++))
                mark=yes
            } || {
                match+='\x1b[44m\'$((counter++))'\x1b[m'
                mark=no
            }
        done
        total+="$search/$match/};"
    done
    sed "$total"
    IFS=$'\n\t '
}

#date +%w => 0 == Sunday    
kanjiday[0]='
.....#############
.....#############
.....##.........##
.....##.........##
.....##.........##
.....#############
.....##.........##
.....##.........##
.....##.........##
.....#############
.....#############'
kanjiday[1]='
.....#############
.....#############
.....##.........##
.....##.........##
.....#############
.....##.........##
.....##.........##
.....#############
.....##.........##
....###.........##
...###.........###'
kanjiday[2]='
..........#.......
......#...#......#
.....##...##....##
.....##...##...##.
.....#....##...#..
..........###.....
.........#..#......
........##..##....
.......##....##...
......##......##..
....###........###.'
kanjiday[3]='
..........##.......
..........##.......
..........##.....#
....#####.##....##
.....####.##...##.
........#.###.##..
.......##.####....
......##..##.##...
.....##...##..##..
.....#....##...##.
.........##.....##'
kanjiday[4]='
..........##......
..........##......
..........##......
....##############
.....############.
.........####.....
........######....
.......##.##.##...
......##..##..##..
.....##...##...##.
....##....##....##'
kanjiday[5]='
..........##......
......####..####..
....##..........##
..................
....##############
..........##......
....##############
.....#....##....#.
......#...##...#..
......#...##...#..
....##############'
kanjiday[6]='
..........##......
..........##......
..........##......
.......########...
......##########..
..........##......
..........##......
..........##......
..........##......
....##############
....##############'

Offline

#1495 2011-08-01 19:28:21

Ashren
Member
From: Denmark
Registered: 2007-06-13
Posts: 1,229
Website

Re: Post your handy self made command line utilities

Procyon: Could you please explain your script in more detail, perhaps commenting it a bit? It is the first I've seen a pipe from a for loop list directly to a while loop and I find it interesting.

What tool do you use to draw the background with? Dzen2 does not react to the input, even though $DAYNR has been set with DAYNR=$(date +%w).

Usage is: command | kanji_background

What does this exactly entail? Which command?

I first thought that it was the builtin "command" you were referring to, but I guess not after reading the man page, but it does look somewhat useful.

Offline

#1496 2011-08-01 20:07:15

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: Post your handy self made command line utilities

@Ashren: Sure.
The drawing is read for alternating characters line by line.

So with
...##..##
..##..##

The while loop will return: 3 2 2 2 (newline) 2 2 2 2

The for loop first line then turns into:
for line in "3 2 2 2" "2 2 2 2"; do
Because IFS is the newline.

The for loop uses those numbers to make a sed line of the form
1{
  s/\(.\{3\}\)\(.\{2\}\)ETC/\1ColorOn\2ColorOff/} #match 3 characters: do nothing. match 2 characters: encase in color code
2{s/ETC}

Before the second for loop IFS is set to space, so the second for loop main line turns into
for color in "3" "2" "2" "2"; do

In which the background alternates on and off.

What tool do you use to draw the background with?

The color code \x1b[44 for the shell.
echo -e '\e[44mTEST\e[m'

I don't have dzen2, but it looks like you would have to change the \x1b[44m to ^bg(blue) and the \x1b[m to ^bg.

With the usage I meant just pipe data to it from any command.

You can test the script by just adding the DAYNR like you said and then:
DAYNR=$(date +%w)
cal -3 | kanji_background

Offline

#1497 2011-08-01 20:26:48

Ashren
Member
From: Denmark
Registered: 2007-06-13
Posts: 1,229
Website

Re: Post your handy self made command line utilities

Procyon: Thank you for the explanation. A very interesting script. I'll experiment with your code a bit so I'll remember such a construction for future reference - I'm sure it will become useful some day.

Offline

#1498 2011-08-01 20:45:20

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: Post your handy self made command line utilities

Ashren:
Yeah, a loop to make a sed statement is fun.
I tried to do it with another sed line, but got stuck with the numbered back references (the \1 \2 \3 stuff).

sed can print line numbers, so it would just turn into:
sed "$(echo drawing | sed $'= a{s/\n s/hashes to dots with color codes/

How I came up with it is that I started out with drawings and then calculating the numbers myself.
So the old version had kanjiday[1]="4 14 newline 4 14 ETC".
Because I wanted to share it I thought I should convert the drawing directly because people would want to make their own.
That's why it looks a bit clunky.

I think you could make it look neater by piping the while loop to the main loop, and replacing that main loop from a for to a while:
while read line
for color
< <(echo Kanjiday | while read -n 1)

Or by changing the array assignment code to the numbers directly.
So
kanjiday[1]=$(echo drawing | while read -n 1)

This saves the script from having to calculate it repeatedly so I think I'll do that.

Last edited by Procyon (2011-08-01 20:49:13)

Offline

#1499 2011-08-02 23:41:54

Fackamato
Member
Registered: 2006-03-31
Posts: 579

Re: Post your handy self made command line utilities

A script to test different I/O schedulers (see this post)

#!/bin/bash
# Test schedulers with iozone
# See https://bbs.archlinux.org/viewtopic.php?pid=969117
# by fackamato, Aug 1, 2011
# changelog:
# 03082011
# Added/fixed: take no. of threads as argument and test accordingly (big rewrite)
# 02082011
# Added: Should now output to a file with the syntax requested by graysky
# Fixed: Add support for HP RAID devices
# Fixed: Drop caches before each test run

if [ "$EUID" -ne "0" ]; then echo "Needs su, exiting"; exit 1; fi

unset ARGS;ARGS=$#
if [ ! $ARGS -lt "5" ]; then
    DEV=$1
    DIR=`echo $2 | sed 's/\/$//g'` # Remove trailing slashes from path
    OUTPUTDIR=`echo $4 | sed 's/\/$//g'` # Remove trailing slashes from path

    # Create the log file directory if it doesn't exist
    if [ ! -d "$OUTPUTDIR" ]; then mkdir -p $OUTPUTDIR;fi

    # Check the test directory
    if [ ! -d "$DIR" ]; then
        echo "Error: Is $DIR a directory?"
        exit 1
    fi

    # Check the device name
    HPDEV="c?d?"
    case "$DEV" in
        $HPDEV ) # HP RAID
            unset SYSDEV;SYSDEV="/sys/block/cciss!$DEV/queue/scheduler"
        ;;
        * )
            unset SYSDEV;SYSDEV="/sys/block/$DEV/queue/scheduler"
        ;;
    esac

    # Check for the output log
    unset OUTPUTLOG;OUTPUTLOG="$OUTPUTDIR/iozone-$DEV-all-results.log"
    if [ -e "$OUTPUTLOG" ]; then echo "$OUTPUTLOG exists, aborting"; exit 1;fi

    # Find available schedulers
    declare -a SCHEDULERS
    SCHEDULERS=`cat $SYSDEV | sed 's/\[//g' | sed 's/\]//g'`
    if [ -z "$SCHEDULERS" ]; then
        echo "No schedulers found! Wrong device specified? Tried looking in $SYSDEV"
        exit 1
    else
        echo "Schedulers found on $DEV: "$SCHEDULERS
        SIZE=$(($3*1024)) # Size is now MB per thread
        unset RUNS; declare -i RUNS;RUNS=$5
    fi

    # Set record size
    if [ -z "$6" ]; then
        echo "Using the default record size of 16MiB"
        RECORDSIZE="16384" # Set default to 16MB
    else
        RECORDSIZE=$6
    fi
    
    # Set no. threads
    if [ -z "$7" ]; then
        echo "Testing with 1, 2 & 3 threads (default)"
        THREADS=3
    else
        THREADS=$7
    fi

    SHELL=`which bash`
else
    echo "# Usage:"
    echo "`basename $0` <dev name> <test dir> <test size in MiB> <log dir> <#runs> <record size> <threads>"
    echo "time ./iozone-scheduler.sh sda /mnt 20480 /dev/shm/server1 3 16 3"
    echo "# The above command will test sda with 1, 2 & 3 threads 3 times per scheduler with 20GiB of data using"
    echo "# 16MiB record size and save logs in /dev/shm/server1/ ."
    echo "# If the record size is omitted the default of 16MiB will be used. (should be buffer size of device)"
    echo "# For HP RAID controllers use device name format c0d0 or c1d2 etc."
    exit 1
fi

function createOutputLog () {
    unset FILE
    echo -e "Test\tThroughput (KB/s)\tI/O Scheduler\tThreads\tn" > $OUTPUTLOG
    for FILE in $OUTPUTDIR/$DEV*.txt; do
        # results
        unset WRITE;unset REWRITE; unset RREAD; unset MIXED; unset RWRITE
        # Scheduler, threads, iteration
        unset SCHED;unset T; unset I;unset IT
        SCHED=`echo "$FILE" | awk -F'-' '{print $2}'`
        T=`echo "$FILE" | awk -F'-' '{print $3}' | sed 's/t//g'`
        # FIXME, it's ugly
        IT=`echo "$FILE" | awk -F'-' '{print $4}'`
        I=`expr ${IT:1:1}`

        # Get values
        WRITE=`grep "  Initial write " $FILE | awk '{print $5}'`
        REWRITE=`grep "        Rewrite " $FILE | awk '{print $4}'`
        RREAD=`grep "    Random read " $FILE | awk '{print $5}'`
        MIXED=`grep " Mixed workload " $FILE | awk '{print $5}'`
        RWRITE=`grep "   Random write " $FILE | awk '{print $5}'`
        # echo "iwrite $WRITE rwrite $REWRITE rread $RREAD mixed $MIXED random $RWRITE"

        # Print to the file
        if [ -z "$WRITE" -o -z "$REWRITE" -o -z "$RREAD" -o -z "$MIXED" -o -z "$RWRITE" ]; then
            # Something's wrong with our input file, or bug in script
            echo "BUG, unable to parse result:"
            echo "write $WRITE rewrite $REWRITE random read $RREAD mixed $MIXED random write $RWRITE"
            exit 1
        else
            echo -e "Initial write\t$WRITE\t$SCHED\t$T\t$I" >> $OUTPUTLOG
            echo -e "Rewrite\t$RWRITE\t$SCHED\t$T\t$I" >> $OUTPUTLOG
            echo -e "Random read\t$RREAD\t$SCHED\t$T\t$I" >> $OUTPUTLOG
            echo -e "Mixed workload\t$MIXED\t$SCHED\t$T\t$I" >> $OUTPUTLOG
            echo -e "Random write\t$RWRITE\t$SCHED\t$T\t$I" >> $OUTPUTLOG
        fi
    done
}

unset ITERATIONS; declare -i ITERATIONS; ITERATIONS=0
unset CURRENTTHREADS; declare -i CURRENTTHREADS
unset IOZONECMD

cd "$DIR"
echo "Using iozone at `which iozone`"

until [ "$ITERATIONS" -ge "$RUNS" ]; do
    let ITERATIONS=$ITERATIONS+1
    for SCHEDULER in $SCHEDULERS; do
        unset IOZONECMDAPPEND
        IOZONECMDAPPEND="$OUTPUTDIR/$DEV-$SCHEDULER-t$THREADS-i$ITERATIONS.txt"
        echo $SCHEDULER > $SYSDEV
        CURRENTTHREADS=1
        until [ $CURRENTTHREADS -gt $THREADS ]; do # Repeat until we reach the requested threads
            # Append all files to the command line (threads/processes)
            unset I; unset IOZONECMD_FILES
            for I in `seq 1 $CURRENTTHREADS`; do
                IOZONECMD_FILES="$IOZONECMD_FILES$DIR/iozone-temp-$I "
            done
            # Drop caches
            echo 3 > /proc/sys/vm/drop_caches
            echo "Testing $SCHEDULER with $CURRENTTHREADS thread(s), run #$ITERATIONS"
            IOZONECMD="iozone -R -i 0 -i 2 -i 8 -s $SIZE -r $RECORDSIZE -b $OUTPUTDIR/$DEV-$SCHEDULER-t$CURRENTTHREADS-i$ITERATIONS.xls -l 1 -u 1 -F $IOZONECMD_FILES"
            # Run the command
            echo time $IOZONECMD
            time $IOZONECMD | tee -a $IOZONEAPPEND
            # Done testing $CURRENTTHREADS threads/processes, increase to test one more in the loop (if applicable)
            let CURRENTTHREADS=$CURRENTTHREADS+1
        done
    done
    echo "Run #$ITERATIONS done" | tee -a $IOZONECMDAPPEND
done

echo
createOutputLog
echo "$ITERATIONS done! FILE saved in $OUTPUTDIR ."

edit: bugfixed

Last edited by Fackamato (2011-08-03 00:10:25)

Offline

#1500 2011-08-03 01:22:26

hauzer
Member
From: Belgrade, Serbia
Registered: 2010-11-17
Posts: 279
Website

Re: Post your handy self made command line utilities

Say you have a directory tree of your favorite songs and albums, this little function will make a recursive list of all files, match them against the argument you've passed and play the matched one. If multiple matches are found, it will play a random one.

# Mplayer Find Play
mpfp () {
  MUSICDIR="${HOME}"/music/
  ISGLOBSTAR='no'

  shopt -p | grep '-s globstar' > /dev/null
  if [[ $? -eq 0 ]] ; then ISGLOBSTAR='yes' ; fi

  shopt -s globstar
  pushd "${MUSICDIR}" > /dev/null
  mplayer "$((((stat ** -c '%n' | egrep '*.*' ) | grep "$1") | sort -R) | tail -n1)"
  popd > /dev/null
  if [[ "${ISGLOBSTAR}" == 'no' ]] ; then shopt -u globstar ; fi
}

Last edited by hauzer (2011-08-03 01:29:22)


Vanity of vanities, saith the Preacher, vanity of vanities; all is vanity.
What profit hath a man of all his labour which he taketh under the sun?
All the rivers run into the sea; yet the sea is not full; unto the place from whence the rivers come, thither they return again.
For in much wisdom is much grief: and he that increaseth knowledge increaseth sorrow.

Offline

Board footer

Powered by FluxBB