You are not logged in.
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
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
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
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
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
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
# ============
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
# ============
Tips and bug reports are welcomed
Offline
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
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
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
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
@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
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
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> </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> </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
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 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
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)...
Offline
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 , 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
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
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
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
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
@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
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
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
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
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