├── .gitignore ├── .newscript_defaults └── sh.txt ├── ChromeSpy ├── chrome_spy.rb └── schema.rb ├── README.md ├── Wicked Cool Scripts ├── .DS_Store ├── 001-inpath.sh ├── 002-validalnum.sh ├── 003-normdate.sh ├── 004-nicenumber.sh ├── 005-validint.sh ├── 006-validfloat.sh ├── 007-valid-date.sh ├── 008-echon.sh ├── 009-scriptbc.sh ├── 010-filelock.sh ├── 011-colors.sh ├── 012-library-test.sh ├── 012-library.sh ├── 013-guessword.sh ├── 013-hilow.sh ├── 014-nfmt.sh ├── 014-ragged.txt ├── 014-ragged.txt.shp ├── 015-newrm.sh ├── 016-unrm.sh ├── 017-logrm.sh ├── 018-formatdir.sh ├── 019-locate.sh ├── 019-mklocatedb.sh ├── 020-DIR.sh ├── 021-findman.sh ├── 022-timein.sh ├── 023-remember.sh ├── 023-remindme.sh ├── 024-calc.sh ├── 025-checkspelling.sh ├── 026-shpell.sh ├── 027-spelldict.sh ├── 028-convertatemp.sh ├── 029-loancalc.sh ├── 030-addagenda.sh ├── 030-agenda.sh ├── 031-numberlines.sh ├── 032-showfile.sh ├── 033-toolong.sh ├── 034-quota.sh ├── 035-mysftp.sh ├── 036-cgrep.sh ├── 037-zcat.sh ├── 038-bestcompress.sh ├── 039-fquota.sh ├── 040-diskhogs.sh ├── 041-diskspace.sh ├── 042-newdf.sh ├── 043-mkslocate.sh ├── 043-slocate.sh ├── 044-adduser.sh ├── 045-suspenduser.sh ├── 046-deleteuser.sh ├── 047-validator.sh ├── 048-fixguest.sh ├── 049-findsuid.sh ├── 050-set-date.sh ├── 051-enabled.sh ├── 052-killall.sh ├── 053-verifycron.sh ├── 054-docron.sh ├── 055-rotatelogs.sh ├── 056-backup.sh ├── 057-archivedir.sh ├── 058-connecttime.sh ├── 059-ftpget.sh ├── 060-bbcnews.sh ├── 061-getlinks.sh ├── 062-define.sh ├── 063-weather.sh ├── 064-checklibrary.sh ├── 065-moviedata.sh ├── 066-exchangerate.sh ├── 066-getexchrate.sh ├── 067-getstock.sh ├── 067-portfolio.sh ├── 068-changetrack.sh ├── 069-showcgienv.sh ├── 070-logsearch.cgi ├── 070-yahoo-search.html ├── 071-getdope.sh ├── 071-kevin-and-kell.cgi ├── 072-contactus.cgi ├── 072-contactus.html ├── 073-photoalbum.cgi ├── 074-guestbook.cgi ├── 074-guestbook.txt ├── 075-counter.sh ├── 075-page-with-counter.html ├── 075-streamfile.cgi ├── 075-updatecounter.sh ├── 076-ssi-sample.html ├── 077-checklinks.sh ├── 078-checkexternal.sh ├── 079-webspell.sh ├── 080-apm-footer.html ├── 080-apm.cgi ├── 080-htpasswd-b.pl ├── 081-ftpsyncup.sh ├── 082-ftpsyncdown.sh ├── 083-sftpsync.sh ├── 083-ssync.sh ├── 084-webaccess.sh ├── 085-enginehits.sh ├── 085-searchinfo.sh ├── 086-weberrors.sh ├── 087-remotebackup-filelist ├── 087-remotebackup.sh ├── 087-trimmailbox.sh ├── 088-unpacker.sh ├── 089-xferlog.sh ├── 090-getstats.sh ├── 090-netperf.sh ├── 091-renicename.sh ├── 091-watch-and-nice.sh ├── 092-addvirtual.sh ├── 093-listmacusers.sh ├── 094-addmacuser.sh ├── 095-addmacalias.sh ├── 096-titleterm.sh ├── 097-itunelist.sh ├── 098-open2.sh ├── 099-unscramble.sh ├── 100-hangman.sh ├── AllFiles.tgz ├── alice.txt.gz ├── big-word-list.txt.gz ├── how-many-commands.sh ├── long-words.txt.gz ├── palindrome.sh ├── ragged.txt ├── sample.crontab ├── state.capitals.txt └── text.snippet.txt ├── bash ├── .zed │ └── settings.json ├── appender.sh ├── arch-reboot.sh ├── arch-updates.sh ├── aws-mfa-access.sh ├── awscli.sh ├── awsmfa.sh ├── awsps1 ├── awswho ├── backup.sh ├── backup_2023-02-16.log ├── buildAll.sh ├── check_service.sh ├── compare.sh ├── daily-note.sh ├── df.sh ├── disk_usage_by_file_type ├── dns-master.sh ├── du_filetype ├── explain ├── finddirtygit.sh ├── fixBrewLionPostgres.sh ├── git-prompt.sh ├── gitbranch.sh ├── gitcmds.sh ├── gitted.sh ├── gitup.sh ├── go_installer.sh ├── gp-split.sh ├── gpvpn-split-mod.sh ├── gpvpn-split.sh ├── handbrakecli ├── headtail.sh ├── help.sh ├── hpost.sh ├── idquery.sh ├── inout.sh ├── inpath ├── kubetail.sh ├── lilypond ├── mac-gp-split.sh ├── mark-whois-script.txt ├── mfa.sh ├── mfatoken.sh ├── mosh.sh ├── myip.sh ├── ng ├── nicenumber ├── nocaps ├── note.sh ├── nsshfs.sh ├── running ├── sessions.sh ├── shrug.sh ├── sslchain.sh ├── svn_check.sh ├── sway-prop ├── template.sh ├── term ├── test.sh ├── thismac.sh ├── tmux-ministart ├── tmux-multistart ├── tmux-sessionizer.sh ├── tmuxip.sh ├── today ├── tsession.sh ├── um.sh ├── valid-date ├── validAlphaNum ├── validfloat ├── validint ├── wifisignal.sh └── zfs.sh ├── deprecated ├── CreateNewWeatherWdgt.sh ├── berksconfig ├── bestcompress.sh ├── catwhich ├── cloneall.sh ├── colors ├── cp_p ├── extractgst.sh ├── loc.sh ├── loch.sh ├── loch.sh.alternative ├── loch.sh.backup ├── login-hook.sh ├── normdate ├── open_ports.sh ├── pair ├── pdbsetup.sh ├── repo ├── settings.sh ├── ssh_host.sh ├── tr.sh ├── tunnel-start.sh └── tweet ├── perl ├── colortest ├── cvs2cl.pl ├── loggy.pl ├── tabdel-print └── weathergeek.pl ├── python ├── converttohugo.py ├── ex_machina.py ├── get_itunes_movie_art.py ├── getip.py ├── git-filter-repo ├── jekylltohugo.py ├── passgen.py ├── pep20_by_example.html ├── sloc2conf.py ├── sloc2group.py ├── sloc2html.py ├── uploadr.history.db ├── uploadr.py ├── words.py ├── xmltramp.py └── zen.py ├── random ├── mark-whois-script.txt ├── mate ├── ngrok └── zz-update-systemd-boot ├── ruby ├── chefdiff.rb ├── newpost.rb ├── rename-node.rb └── unfollowers.rb ├── rubygems ├── htmldiff ├── kramdown ├── ldiff ├── nokogiri ├── reverse_markdown ├── rubocop ├── ruby-parse ├── ruby-rewrite ├── solargraph ├── thor ├── tilt ├── yard ├── yardoc └── yri ├── twitter ├── followers.csv └── mycrontab └── zsh ├── electron-version.sh ├── git-authorship └── git-today /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | *.py[cod] 4 | *.DS_Store 5 | -------------------------------------------------------------------------------- /.newscript_defaults/sh.txt: -------------------------------------------------------------------------------- 1 | set -e 2 | set -o pipefail 3 | 4 | # script 5 | # 6 | # Description 7 | # 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | bin 2 | === 3 | 4 | Various shell scripts 5 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanshin/bin/251da0aafdd46479e789ab2fe8762ac767ab1662/Wicked Cool Scripts/.DS_Store -------------------------------------------------------------------------------- /Wicked Cool Scripts/001-inpath.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # inpath - verify that a specified program is either valid as-is, 3 | # or can be found in the PATH directory list. 4 | 5 | in_path() 6 | { 7 | # given a command and the PATH, try to find the command. Returns 8 | # 0 if found and executable, 1 if not. Note that this temporarily modifies 9 | # the the IFS (input field seperator), but restores it upon completion. 10 | 11 | cmd=$1 path=$2 retval=1 12 | oldIFS=$IFS IFS=":" 13 | 14 | for directory in $path 15 | do 16 | if [ -x $directory/$cmd ] ; then 17 | retval=0 # if we're here, we found $cmd in $directory 18 | fi 19 | done 20 | IFS=$oldIFS 21 | return $retval 22 | } 23 | 24 | checkForCmdInPath() 25 | { 26 | var=$1 27 | 28 | # The variable slicing notation in the following conditional 29 | # needs some explanation: ${var#expr} returns everything after 30 | # the match for 'expr' in the variable value (if any), and 31 | # ${var%expr} returns everything that doesn't match (in this 32 | # case just the very first character. You can also do this in 33 | # Bash with ${var:0:1} and you could use cut too: cut -c1 34 | 35 | if [ "$var" != "" ] ; then 36 | if [ "${var%${var#?}}" = "/" ] ; then 37 | if [ ! -x $var ] ; then 38 | return 1 39 | fi 40 | elif ! in_path $var $PATH ; then 41 | return 2 42 | fi 43 | fi 44 | } 45 | 46 | if [ $# -ne 1 ] ; then 47 | echo "Usage: $0 command" >&2 ; exit 1 48 | fi 49 | 50 | checkForCmdInPath "$1" 51 | case $? in 52 | 0 ) echo "$1 found in PATH" ;; 53 | 1 ) echo "$1 not found or not executable" ;; 54 | 2 ) echo "$1 not found in PATH" ;; 55 | esac 56 | 57 | exit 0 58 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/002-validalnum.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # validalAlphaNum - Ensures that input only consists of alphabetical 3 | # and numeric characters. 4 | 5 | validAlphaNum() 6 | { 7 | # validate arg: returns 0 if all upper+lower+digits, 1 otherwise 8 | 9 | # Remove all unacceptable chars 10 | compressed="$(echo $1 | sed -e 's/[^[:alnum:]]//g')" 11 | 12 | if [ "$compressed" != "$input" ] ; then 13 | return 1 14 | else 15 | return 0 16 | fi 17 | } 18 | 19 | # Sample usage of this function in a script 20 | 21 | echo -n "Enter input: " 22 | read input 23 | 24 | if ! validAlphaNum "$input" ; then 25 | echo "Your input must consist of only letters and numbers." >&2 26 | exit 1 27 | else 28 | echo "Input is valid." 29 | fi 30 | 31 | exit 0 32 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/003-normdate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # normdate - Normalizes month field in date specification 3 | # to three letters, first letter capitalized. A helper 4 | # function for hack #7, validdate. Exits w/ zero if no error. 5 | 6 | monthnoToName() 7 | { 8 | # sets the variable 'month' to the appropriate value 9 | case $1 in 10 | 1 ) month="Jan" ;; 2 ) month="Feb" ;; 11 | 3 ) month="Mar" ;; 4 ) month="Apr" ;; 12 | 5 ) month="May" ;; 6 ) month="Jun" ;; 13 | 7 ) month="Jul" ;; 8 ) month="Aug" ;; 14 | 9 ) month="Sep" ;; 10) month="Oct" ;; 15 | 11) month="Nov" ;; 12) month="Dec" ;; 16 | * ) echo "$0: Unknown numeric month value $1" >&2; exit 1 17 | esac 18 | return 0 19 | } 20 | 21 | ## Begin main script 22 | 23 | if [ $# -eq 1 ] ; then # try to compensate for / or - formats 24 | set -- $(echo $1 | sed 's/[\/\-]/ /g') 25 | fi 26 | 27 | if [ $# -ne 3 ] ; then 28 | echo "Usage: $0 month day year" >&2 29 | echo "Typical input formats are August 3 1962 and 8 3 2002" >&2 30 | exit 1 31 | fi 32 | 33 | if [ $3 -lt 99 ] ; then 34 | echo "$0: expected four-digit year value." >&2; exit 1 35 | fi 36 | 37 | if [ -z $(echo $1|sed 's/[[:digit:]]//g') ]; then 38 | monthnoToName $1 39 | else 40 | # normalize to first three letters, first upper, rest lowercase 41 | month="$(echo $1|cut -c1|tr '[:lower:]' '[:upper:]')" 42 | month="$month$(echo $1|cut -c2-3 | tr '[:upper:]' '[:lower:]')" 43 | fi 44 | 45 | echo $month $2 $3 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/004-nicenumber.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # nicenumber - given a number, show it with comma separated values 4 | # expects DD and TD to be instantiated. instantiates nicenum 5 | # or, if a second arg is specified, the output is echoed to stdout 6 | 7 | nicenumber() 8 | { 9 | # Note that we use the '.' as the decimal separator for parsing 10 | # the INPUT value to this script. The output value is as specified 11 | # by the user with the -d flag, if different from a '.' 12 | 13 | integer=$(echo $1 | cut -d. -f1) # left of the decimal 14 | decimal=$(echo $1 | cut -d. -f2) # right of the decimal 15 | 16 | if [ $decimal != $1 ]; then 17 | # there's a fractional part, let's include it. 18 | result="${DD:="."}$decimal" 19 | fi 20 | 21 | thousands=$integer 22 | 23 | while [ $thousands -gt 999 ]; do 24 | remainder=$(($thousands % 1000)) # three least significant digits 25 | 26 | while [ ${#remainder} -lt 3 ] ; do # force leading zeroes as needed 27 | remainder="0$remainder" 28 | done 29 | 30 | thousands=$(($thousands / 1000)) # to left of remainder, if any 31 | result="${TD:=","}${remainder}${result}" # builds right-to-left 32 | done 33 | 34 | nicenum="${thousands}${result}" 35 | if [ ! -z $2 ] ; then 36 | echo $nicenum 37 | fi 38 | } 39 | 40 | DD="." # decimal point delimiter, between integer & fractional value 41 | TD="," # thousands delimiter, separates every three digits 42 | 43 | while getopts "d:t:" opt; do 44 | case $opt in 45 | d ) DD="$OPTARG" ;; 46 | t ) TD="$OPTARG" ;; 47 | esac 48 | done 49 | 50 | shift $(($OPTIND - 1)) 51 | 52 | if [ $# -eq 0 ] ; then 53 | cat << "EOF" >&2 54 | Usage: $(basename $0) [-d c] [-t c] numeric value 55 | -d specifies the decimal point delimiter (default '.') 56 | -t specifies the thousands delimiter (default ',') 57 | EOF 58 | exit 1 59 | fi 60 | 61 | nicenumber $1 1 # second arg forces this to 'echo' output 62 | 63 | exit 0 64 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/005-validint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # validint - validate integer input, allow negative ints too 3 | 4 | validint() 5 | { 6 | # validate first field. Optionally test against min value $2 and/or 7 | # max value $3: if you'd rather skip these tests, send "" as values. 8 | # returns 1 for error, 0 for success. 9 | 10 | number="$1"; min="$2"; max="$3" 11 | 12 | if [ -z $number ] ; then 13 | echo "You didn't enter anything. Unacceptable." >&2 ; return 1 14 | fi 15 | 16 | if [ "${number%${number#?}}" = "-" ] ; then # first char '-' ? 17 | testvalue="${number#?}" # all but first character 18 | else 19 | testvalue="$number" 20 | fi 21 | 22 | nodigits="$(echo $testvalue | sed 's/[[:digit:]]//g')" 23 | 24 | if [ ! -z $nodigits ] ; then 25 | echo "Invalid number format! Only digits, no commas, spaces, etc." >&2 26 | return 1 27 | fi 28 | 29 | if [ ! -z $min ] ; then 30 | if [ "$number" -lt "$min" ] ; then 31 | echo "Your value is too small: smallest acceptable value is $min" >&2 32 | return 1 33 | fi 34 | fi 35 | if [ ! -z $max ] ; then 36 | if [ "$number" -gt "$max" ] ; then 37 | echo "Your value is too big: largest acceptable value is $max" >&2 38 | return 1 39 | fi 40 | fi 41 | return 0 42 | } 43 | 44 | # uncomment these lines to test, but beware that it'll break Hack #6 45 | # because Hack #6 wants to source this file to get the validint() 46 | # function. :-) 47 | 48 | # if validint "$1" "$2" "$3" ; then 49 | # echo "That input is a valid integer value within your constraints" 50 | # fi 51 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/006-validfloat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # validfloat - test whether a number is a valid floating point value. 4 | # Note that this cannot accept scientific (1.304e5) notation. 5 | 6 | # To test whether an entered value is a valid floating point number, we 7 | # need to split the value at the decimal point, then test the first part 8 | # to see if it's a valid integer, then the second part to see if it's a 9 | # valid >=0 integer, so -30.5 is valid, but -30.-8 isn't. 10 | 11 | . 005-validint.sh # source the validint function 12 | 13 | validfloat() 14 | { 15 | fvalue="$1" 16 | 17 | if [ ! -z $(echo $fvalue | sed 's/[^.]//g') ] ; then 18 | 19 | decimalPart="$(echo $fvalue | cut -d. -f1)" 20 | fractionalPart="$(echo $fvalue | cut -d. -f2)" 21 | 22 | if [ ! -z $decimalPart ] ; then 23 | if ! validint "$decimalPart" "" "" ; then 24 | return 1 25 | fi 26 | fi 27 | 28 | if [ "${fractionalPart%${fractionalPart#?}}" = "-" ] ; then 29 | echo "Invalid floating point number: '-' not allowed \ 30 | after decimal point" >&2 31 | return 1 32 | fi 33 | if [ "$fractionalPart" != "" ] ; then 34 | if ! validint "$fractionalPart" "0" "" ; then 35 | return 1 36 | fi 37 | fi 38 | 39 | if [ "$decimalPart" = "-" -o -z $decimalPart ] ; then 40 | if [ -z $fractionalPart ] ; then 41 | echo "Invalid floating point format." >&2 ; return 1 42 | fi 43 | fi 44 | 45 | else 46 | if [ "$fvalue" = "-" ] ; then 47 | echo "Invalid floating point format." >&2 ; return 1 48 | fi 49 | 50 | if ! validint "$fvalue" "" "" ; then 51 | return 1 52 | fi 53 | fi 54 | 55 | return 0 56 | } 57 | 58 | if validfloat $1 ; then 59 | echo "$1 is a valid floating point value" 60 | fi 61 | 62 | exit 0 63 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/008-echon.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # echon - a script to emulate the -n flag functionality with 'echo' 4 | # for Unix systems that don't have that available. 5 | 6 | echon() 7 | { 8 | echo "$*" | tr -d '\n' 9 | } 10 | 11 | echon "this is a test: " 12 | read answer 13 | 14 | echon this is a test too " " 15 | read answer2 16 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/009-scriptbc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # scriptbc - wrapper for 'bc' that returns the value of a formula 4 | 5 | if [ $1 = "-p" ] ; then 6 | precision=$2 7 | shift 2 8 | else 9 | precision=2 # default 10 | fi 11 | 12 | bc -q -l << EOF 13 | scale=$precision 14 | $* 15 | quit 16 | EOF 17 | 18 | exit 0 19 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/010-filelock.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # filelock - a flexible file locking mechanism 4 | 5 | retries="10" # default number of retries: 10 6 | action="lock" # default action 7 | nullcmd="/bin/true" # null command for lockf 8 | 9 | while getopts "lur:" opt; do 10 | case $opt in 11 | l ) action="lock" ;; 12 | u ) action="unlock" ;; 13 | r ) retries="$OPTARG" ;; 14 | esac 15 | done 16 | shift $(($OPTIND - 1)) 17 | 18 | if [ $# -eq 0 ] ; then 19 | cat << EOF >&2 20 | Usage: $0 [-l|-u] [-r retries] lockfilename 21 | Where -l requests a lock (the default), -u requests an unlock, -r X 22 | specifies a maximum number of retries before it fails (default = $retries). 23 | EOF 24 | exit 1 25 | fi 26 | 27 | # ascertain whether we have lockf or lockfile system apps 28 | 29 | if [ -z "$(which lockfile | grep -v '^no ')" ] ; then 30 | echo "$0 failed: 'lockfile' utility not found in PATH." >&2 31 | exit 1 32 | fi 33 | 34 | if [ "$action" = "lock" ] ; then 35 | if ! lockfile -1 -r $retries "$1" 2> /dev/null; then 36 | echo "$0: Failed: Couldn't create lockfile in time" >&2 37 | exit 1 38 | fi 39 | else # action = unlock 40 | if [ ! -f "$1" ] ; then 41 | echo "$0: Warning: lockfile $1 doesn't exist to unlock" >&2 42 | exit 1 43 | fi 44 | rm -f "$1" 45 | fi 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/011-colors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # ANSI Color -- use these variables to easily have different color 4 | # and format output. Make sure to output the reset sequence after 5 | # colors (f = foreground, b = background), and use the 'off' 6 | # feature for anything you turn on. 7 | 8 | initializeANSI() 9 | { 10 | esc="" 11 | 12 | blackf="${esc}[30m"; redf="${esc}[31m"; greenf="${esc}[32m" 13 | yellowf="${esc}[33m" bluef="${esc}[34m"; purplef="${esc}[35m" 14 | cyanf="${esc}[36m"; whitef="${esc}[37m" 15 | 16 | blackb="${esc}[40m"; redb="${esc}[41m"; greenb="${esc}[42m" 17 | yellowb="${esc}[43m" blueb="${esc}[44m"; purpleb="${esc}[45m" 18 | cyanb="${esc}[46m"; whiteb="${esc}[47m" 19 | 20 | boldon="${esc}[1m"; boldoff="${esc}[22m" 21 | italicson="${esc}[3m"; italicsoff="${esc}[23m" 22 | ulon="${esc}[4m"; uloff="${esc}[24m" 23 | invon="${esc}[7m"; invoff="${esc}[27m" 24 | 25 | reset="${esc}[0m" 26 | } 27 | 28 | # note in this first use that switching colors doesn't require a reset 29 | # first - the new color overrides the old one. 30 | 31 | initializeANSI 32 | 33 | cat << EOF 34 | ${yellowf}This is a phrase in yellow${redb} and red${reset} 35 | ${boldon}This is bold${ulon} this is italics${reset} bye bye 36 | ${italicson}This is italics${italicsoff} and this is not 37 | ${ulon}This is ul${uloff} and this is not 38 | ${invon}This is inv${invoff} and this is not 39 | ${yellowf}${redb}Warning I${yellowb}${redf}Warning II${reset} 40 | EOF 41 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/012-library-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Script to demonstrate use of the shell function library 4 | 5 | . 012-library.sh 6 | 7 | initializeANSI 8 | 9 | echon "First off, do you have echo in your path? (1=yes, 2=no) " 10 | read answer 11 | while ! validint $answer 1 2 ; do 12 | echon "${boldon}Try again${boldoff}. Do you have echo " 13 | echon "in your path? (1=yes, 2=no) " 14 | read answer 15 | done 16 | 17 | if ! checkForCmdInPath "echo" ; then 18 | echo "Nope, can't find the echo command." 19 | else 20 | echo "The echo command is in the PATH." 21 | fi 22 | 23 | echo "" 24 | echon "Enter a year you think might be a leap year: " 25 | read year 26 | 27 | while ! validint $year 1 9999 ; do 28 | echon "Please enter a year in the ${boldon}correct${boldoff} format: " 29 | read year 30 | done 31 | 32 | if isLeapYear $year ; then 33 | echo "${greenf}You're right! $year was a leap year.${reset}" 34 | else 35 | echo "${redf}Nope, that's not a leap year.${reset}" 36 | fi 37 | 38 | exit 0 39 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/013-hilow.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # hilow - a simple number guessing game 3 | 4 | biggest=100 # maximum number possible 5 | guess=0 # guessed by player 6 | guesses=0 # number of guesses made 7 | number=$(( $$ % $biggest )) # random number, 1 .. $biggest 8 | 9 | while [ $guess -ne $number ] ; do 10 | echo -n "Guess? " ; read guess 11 | if [ "$guess" -lt $number ] ; then 12 | echo "... bigger!" 13 | elif [ "$guess" -gt $number ] ; then 14 | echo "... smaller!" 15 | fi 16 | guesses=$(( $guesses + 1 )) 17 | done 18 | 19 | echo "Right!! Guessed $number in $guesses guesses." 20 | 21 | exit 0 22 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/014-nfmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # nfmt - A version of fmt, using nroff. Adds two useful flags: -w X for 4 | # line width and -h to enable hyphenation for better fills. 5 | 6 | while getopts "hw:" opt; do 7 | case $opt in 8 | h ) hyph=1 ;; 9 | w ) width="$OPTARG" ;; 10 | esac 11 | done 12 | shift $(($OPTIND - 1)) 13 | 14 | nroff << EOF 15 | .ll ${width:-72} 16 | .na 17 | .hy ${hyph:-0} 18 | .pl 1 19 | $(cat "$@") 20 | EOF 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/014-ragged.txt: -------------------------------------------------------------------------------- 1 | So she sat on, with closed eyes, and half believed herrself in 2 | Wonderland, though she knew she had but to open them again, and 3 | all would change to dull reality--the grass would be only rustling in the wind, and the pool rippling to the waving of the reeds--the 4 | rattling teacups would change to tinkling sheep- bells, and the 5 | Queen's shrill cries to the voice of the shepherd boy--and the 6 | sneeze 7 | of the baby, the shriek of the Gryphon, and all thy other queer noises, would change (she knew) 8 | to the confused clamour of the busy farm-yard--while the lowing of 9 | the cattle in 10 | the distance would take the place of the Mock Turtle's heavy sobs. 11 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/014-ragged.txt.shp: -------------------------------------------------------------------------------- 1 | So she sat on, with closed eyes, and half believed herrself in 2 | Wonderland, though she knew she had but to open them again, and 3 | all would change to dull reality--the grass would be only rustling in the wind, and the pool reippling to the waving of the reeds--the 4 | rattling teacups would change to tinkling sheep- bells, and the 5 | Queen's shrill cries to the voice of the shepherd boy--and the 6 | sneeze 7 | of the baby, the shriek of the Gryphon, and all thy other queer noises, would change (she knew) 8 | to the confused clamour of the busy farm-yard--while the lowing of 9 | the cattle in 10 | the distance would take the place of the Mock Turtle's heavy sobs. 11 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/015-newrm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # newrm - a replacement for the existing rm command that allows a 4 | # rudimentary unremove capability through utilizing a newly created 5 | # directory in the user's home directory. It can handle directories 6 | # of content as well as individual files, and if the user specifies 7 | # the -f flag, files are NOT archived, but removed. 8 | 9 | # Big Important Warning: you'll want a cron job or similar to keep the 10 | # individual trash directories tamed, otherwise nothing will ever 11 | # actually be deleted on the system and you'll run out of disk space! 12 | 13 | mydir="$HOME/.deleted-files" 14 | realrm="/bin/rm " 15 | copy="/bin/cp -R" 16 | 17 | if [ $# -eq 0 ] ; then # let 'rm' ouptut the usage error 18 | exec $realrm # our shell dies and is replaced by /bin/rm 19 | fi 20 | 21 | # parse all options looking for '-f' 22 | 23 | flags="" 24 | 25 | while getopts "dfiPRrvW" opt 26 | do 27 | case $opt in 28 | f ) exec $realrm "$@" ;; # exec lets us exit this script directly. 29 | * ) flags="$flags -$opt" ;; # other flags are for 'rm', not us 30 | esac 31 | done 32 | shift $(( $OPTIND - 1 )) 33 | 34 | # make sure that the $mydir exists 35 | 36 | if [ ! -d $mydir ] ; then 37 | if [ ! -w $HOME ] ; then 38 | echo "$0 failed: can't create $mydir in $HOME" >&2 39 | exit 1 40 | fi 41 | mkdir $mydir 42 | chmod 700 $mydir # a little bit of privacy, please 43 | fi 44 | 45 | for arg 46 | do 47 | newname="$mydir/$(date "+%S.%M.%H.%d.%m").$(basename "$arg")" 48 | if [ -f "$arg" ] ; then 49 | $copy "$arg" "$newname" 50 | elif [ -d "$arg" ] ; then 51 | $copy "$arg" "$newname" 52 | fi 53 | done 54 | 55 | exec $realrm $flags "$@" # our shell is replaced by realrm 56 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/017-logrm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # logrm - log all file deletion requests unless "-s" flag is used 3 | 4 | removelog="/tmp/removelog.log" 5 | 6 | if [ $# -eq 0 ] ; then 7 | echo "Usage: $0 [-s] list of files or directories" >&2 8 | exit 1 9 | fi 10 | 11 | if [ "$1" = "-s" ] ; then 12 | # silent operation requested... don't log 13 | shift 14 | else 15 | echo "$(date): ${USER}: $@" >> $removelog 16 | fi 17 | 18 | /bin/rm "$@" 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/018-formatdir.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # formatdir - output a directory listing in a friendly and useful format 4 | 5 | gmk() 6 | { 7 | # given input in Kb, output in Kb, Mb or Gb for best output format 8 | if [ $1 -ge 1000000 ] ; then 9 | echo "$(scriptbc -p 2 $1 / 1000000)Gb" 10 | elif [ $1 -ge 1000 ] ; then 11 | echo "$(scriptbc -p 2 $1 / 1000)Mb" 12 | else 13 | echo "${1}Kb" 14 | fi 15 | } 16 | 17 | if [ $# -gt 1 ] ; then 18 | echo "Usage: $0 [dirname]" >&2; exit 1 19 | elif [ $# -eq 1 ] ; then 20 | cd "$@" 21 | fi 22 | 23 | for file in * 24 | do 25 | if [ -d "$file" ] ; then 26 | size=$(ls "$file" | wc -l | sed 's/[^[:digit:]]//g') 27 | if [ $size -eq 1 ] ; then 28 | echo "$file ($size entry)|" 29 | else 30 | echo "$file ($size entries)|" 31 | fi 32 | else 33 | size="$(ls -sk "$file" | awk '{print $1}')" 34 | echo "$file ($(gmk $size))|" 35 | fi 36 | done | \ 37 | sed 's/ /^^^/g' | \ 38 | xargs -n 2 | \ 39 | sed 's/\^\^\^/ /g' | \ 40 | awk -F\| '{ printf "%-39s %-39s\n", $1, $2 }' 41 | 42 | exit 0 43 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/019-locate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # locate - search the locate database for the specified pattern 4 | 5 | locatedb="/var/locate.db" 6 | 7 | exec grep -i "$@" $locatedb 8 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/019-mklocatedb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # mklocatedb - build the locate database using find. Must be root to run this 4 | 5 | locatedb="/var/locate.db" 6 | 7 | if [ "$(whoami)" != "root" ] ; then 8 | echo "Must be root to run this command." >&2 9 | exit 1 10 | fi 11 | 12 | find / -print > $locatedb 13 | 14 | exit 0 15 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/020-DIR.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # DIR - pretend we're the DIR command in DOS and display the contents 3 | # of the specified file, accepting some of the standard DIR flags 4 | 5 | usage() 6 | { 7 | cat << EOF >&2 8 | Usage: $0 [DOS flags] directory or directories 9 | Where: 10 | /D sort by columns 11 | /H show help for this shell script 12 | /N show long listing format with filenames on right 13 | /OD sort by oldest to newest 14 | /O-D sort by newest to oldest 15 | /P pause after each screenful of information 16 | /Q show owner of the file 17 | /S recursive listing 18 | /W use wide listing format 19 | EOF 20 | exit 0 21 | } 22 | 23 | postcmd="" 24 | flags="" 25 | 26 | while [ $# -gt 0 ] 27 | do 28 | case $1 in 29 | /D ) flags="$flags -x" ;; 30 | /H ) usage ;; 31 | /[NQW] ) flags="$flags -l" ;; 32 | /OD ) flags="$flags -rt" ;; 33 | /O-D ) flags="$flags -t" ;; 34 | /P ) postcmd="more" ;; 35 | /S ) flags="$flags -s" ;; 36 | * ) # unknown flag: probably a dir specifier 37 | break; # so let's get outta the while loop 38 | esac 39 | shift # processed flag, let's see if there's another 40 | done 41 | 42 | # done processing flags, now the command itself: 43 | 44 | if [ ! -z "$postcmd" ] ; then 45 | ls $flags "$@" | $postcmd 46 | else 47 | ls $flags "$@" 48 | fi 49 | 50 | exit 0 51 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/021-findman.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # findman -- given a pattern and a man section, show all the matches 4 | # for that pattern from within all relevant man pages. 5 | 6 | match1="/tmp/$0.1.$$" 7 | matches="/tmp/$0.$$" 8 | manpagelist="" 9 | 10 | trap "rm -f $match1 $matches" EXIT 11 | 12 | case $# 13 | in 14 | 3 ) section="$1" cmdpat="$2" manpagepat="$3" ;; 15 | 2 ) section="" cmdpat="$1" manpagepat="$2" ;; 16 | * ) echo "Usage: $0 [section] cmdpattern manpagepattern" >&2 17 | exit 1 18 | esac 19 | 20 | if ! man -k "$cmdpat" | grep "($section" > $match1 ; then 21 | echo "No matches to pattern \"$cmdpat\". Try something broader?"; exit 1 22 | fi 23 | 24 | cut -d\( -f1 < $match1 > $matches # command names only 25 | cat /dev/null > $match1 # clear the file... 26 | 27 | for manpage in $(cat $matches) 28 | do 29 | manpagelist="$manpagelist $manpage" 30 | man $manpage | col -b | grep -i $manpagepat | \ 31 | sed "s/^/${manpage}: /" | tee -a $match1 32 | done 33 | 34 | if [ ! -s $match1 ] ; then 35 | cat << EOF 36 | Command pattern "$cmdpat" had matches, but within those there were no 37 | matches to your man page pattern "$manpagepat" found in that set. 38 | Man pages checked:$manpagelist 39 | EOF 40 | fi 41 | 42 | exit 0 43 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/023-remember.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # remember - an easy command-line based memory pad 4 | # search the results with 'remindme' 5 | 6 | rememberfile="$HOME/.remember" 7 | 8 | if [ $# -eq 0 ] ; then 9 | echo "Enter note, end with ^D: " 10 | cat - >> $rememberfile 11 | else 12 | echo "$@" >> $rememberfile 13 | fi 14 | 15 | exit 0 16 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/023-remindme.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # remindme - search a datafile for matching lines, or show the contents 4 | # of the datafile if no arg is specified 5 | 6 | rememberfile="$HOME/.remember" 7 | 8 | if [ $# -eq 0 ] ; then 9 | more $rememberfile 10 | else 11 | grep -i "$@" $rememberfile | ${PAGER:-more} 12 | fi 13 | 14 | exit 0 15 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/024-calc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # calc - a command-line calculator that acts as a front-end to bc 4 | 5 | scale=2 6 | 7 | show_help() 8 | { 9 | cat << EOF 10 | In addition to standard math functions, calc also supports 11 | 12 | a % b remainder of a/b 13 | a ^ b exponential: a raised to the b power 14 | s(x) sine of x, x in radians 15 | c(x) cosine of x, x in radians 16 | a(x) arctangent of x, returns radians 17 | l(x) natural log of x 18 | e(x) exponential log of raising e to the x 19 | j(n,x) bessel function of integer order n of x 20 | scale N show N fractional digits (default = 2) 21 | EOF 22 | } 23 | 24 | if [ $# -gt 0 ] ; then 25 | exec scriptbc "$@" 26 | fi 27 | 28 | echo "Calc - a simple calculator. Use 'help' for help, 'quit' to quit." 29 | 30 | echo -n "calc> " 31 | 32 | while read command args 33 | do 34 | case $command 35 | in 36 | quit|exit) exit 0 ;; 37 | help|\?) show_help ;; 38 | scale) scale=$args ;; 39 | *) scriptbc -p $scale "$command" "$args" ;; 40 | esac 41 | 42 | echo -n "calc> " 43 | done 44 | 45 | echo "" 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/025-checkspelling.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # checkspelling - check the spelling of a word 4 | 5 | spell="ispell -l" # if you have ispell installed instead 6 | # if not, just define spell=spell or 7 | # equivalent. 8 | 9 | if [ $# -lt 1 ] ; then 10 | echo "Usage: $0 word or words" >&2 11 | exit 1 12 | fi 13 | 14 | for word 15 | do 16 | if [ -z $(echo $word | $spell) ] ; then 17 | echo "$word: spelled correctly." 18 | else 19 | echo "$word: misspelled." 20 | fi 21 | done 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/027-spelldict.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # spelldict - use the 'aspell' feature and some filtering to allow easy 4 | # command-line spell checking of a given input (file) 5 | 6 | okaywords="$HOME/.okaywords" 7 | tempout="/tmp/spell.tmp.$$" 8 | spell="virtual aspell" # tweak as needed 9 | 10 | trap "/bin/rm -f $tempout" EXIT 11 | 12 | if [ -z "$1" ] ; then 13 | echo "Usage: spell file|URL" >&2; exit 1 14 | elif [ ! -f $okaywords ] ; then 15 | echo "No personal dictionary found. Create one and rerun this command" >&2 16 | echo "Your dictionary file: $okaywords" >&2 17 | exit 1 18 | fi 19 | 20 | for filename 21 | do 22 | $spell -a < $filename | \ 23 | grep -v '@(#)' | sed "s/\'//g" | \ 24 | awk '{ if (length($0) > 15 && length($2) > 2) print $2 }' | \ 25 | grep -vif $okaywords | \ 26 | grep '[[:lower:]]' | grep -v '[[:digit:]]' | sort -u | \ 27 | sed 's/^/ /' > $tempout 28 | 29 | if [ -s $tempout ] ; then 30 | sed "s/^/${filename}: /" $tempout 31 | fi 32 | done 33 | 34 | exit 0 35 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/028-convertatemp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # CONVERTATEMP - Temperature conversion script that lets the user enter 4 | # a temperature in any of Fahrenheit, Celsius or Kelvin and receive the 5 | # equivalent temperature in the other two units as the output. 6 | 7 | if uname | grep 'SunOS'>/dev/null ; then 8 | echo "Yep, SunOS, let\'s fix this baby" 9 | PATH="/usr/xpg4/bin:$PATH" 10 | fi 11 | 12 | if [ $# -eq 0 ] ; then 13 | cat << EOF >&2 14 | Usage: $0 temperature[F|C|K] 15 | where the suffix: 16 | F indicates input is in Fahrenheit (default) 17 | C indicates input is in Celsius 18 | K indicates input is in Kelvin 19 | EOF 20 | exit 1 21 | fi 22 | 23 | unit="$(echo $1|sed -e 's/[-[[:digit:]]*//g' | tr '[:lower:]' '[:upper:]' )" 24 | temp="$(echo $1|sed -e 's/[^-[[:digit:]]*//g')" 25 | 26 | case ${unit:=F} 27 | in 28 | F ) # Fahrenheit to Celsius formula: Tc = (F -32 ) / 1.8 29 | farn="$temp" 30 | cels="$(echo "scale=2;($farn - 32) / 1.8" | bc)" 31 | kelv="$(echo "scale=2;$cels + 273.15" | bc)" 32 | ;; 33 | 34 | C ) # Celsius to Fahrenheit formula: Tf = (9/5)*Tc+32 35 | cels=$temp 36 | kelv="$(echo "scale=2;$cels + 273.15" | bc)" 37 | farn="$(echo "scale=2;((9/5) * $cels) + 32" | bc)" 38 | ;; 39 | 40 | K ) # Celsius = Kelvin + 273.15, then use Cels -> Fahr formula 41 | kelv=$temp 42 | cels="$(echo "scale=2; $kelv - 273.15" | bc)" 43 | farn="$(echo "scale=2; ((9/5) * $cels) + 32" | bc)" 44 | esac 45 | 46 | echo "Fahrenheit = $farn" 47 | echo "Celsius = $cels" 48 | echo "Kelvin = $kelv" 49 | 50 | exit 0 51 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/029-loancalc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # mortgage - given a principal loan amount, interest rate, and 4 | # duration of loan (years), calculate the per-payment amount. 5 | 6 | # formula is: M = P * ( J / (1 - (1 + J) ** -N)) 7 | # where P = principal, J = monthly interest rate, N = duration (months) 8 | # 9 | # users typically enter P, I (annual interest rate) and L (length, years) 10 | 11 | . 012-library.sh 12 | 13 | if [ $# -ne 3 ] ; then 14 | echo "Usage: $0 principal interest loan-duration-years" >&2 15 | exit 1 16 | fi 17 | 18 | P=$1 I=$2 L=$3 19 | J="$(scriptbc -p 8 $I / \( 12 \* 100 \) )" 20 | N="$(( $L * 12 ))" 21 | M="$(scriptbc -p 8 $P \* \( $J / \(1 - \(1 + $J\) \^ -$N\) \) )" 22 | 23 | # now a little prettying up of the value: 24 | 25 | dollars="$(echo $M | cut -d. -f1)" 26 | cents="$(echo $M | cut -d. -f2 | cut -c1-2)" 27 | 28 | cat << EOF 29 | A $L year loan at $I% interest with a principal amount of $(nicenumber $P 1 ) 30 | results in a payment of \$$dollars.$cents each month for the duration of 31 | the loan ($N payments). 32 | EOF 33 | 34 | exit 0 35 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/030-agenda.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # agenda - scan through the user's .agenda file to see if there 4 | # are any matches for the current or next day 5 | 6 | agendafile="$HOME/.agenda" 7 | 8 | checkDate() 9 | { 10 | # create the possible default values that'll match today 11 | weekday=$1 day=$2 month=$3 year=$4 12 | format1="$weekday" format2="$day$month" format3="$day$month$year" 13 | 14 | # and step through the file comparing dates... 15 | 16 | IFS="|" # The reads will naturally split at the IFS 17 | 18 | echo "On the Agenda for today:" 19 | 20 | while read date description ; do 21 | if [ "$date" = "$format1" -o "$date" = "$format2" -o "$date" = "$format3" ] 22 | then 23 | echo " $description" 24 | fi 25 | done < $agendafile 26 | } 27 | 28 | if [ ! -e $agendafile ] ; then 29 | echo "$0: You don't seem to have an .agenda file. " >&2 30 | echo "To remedy this, please use 'addagenda' to add events" >&2 31 | exit 1 32 | fi 33 | 34 | # now let's get today's date... 35 | 36 | eval $(date "+weekday=\"%a\" month=\"%b\" day=\"%e\" year=\"%G\"") 37 | 38 | day="$(echo $day|sed 's/ //g')" # remove possible leading space 39 | 40 | checkDate $weekday $day $month $year 41 | 42 | exit 0 43 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/031-numberlines.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # numberlines - a simple alternative to cat -n, etc 4 | 5 | for filename 6 | do 7 | linecount="1" 8 | (while read line 9 | do 10 | echo "${linecount}: $line" 11 | linecount="$(( $linecount + 1 ))" 12 | done) < $filename 13 | done 14 | 15 | exit 0 16 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/032-showfile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # showfile - show the contents of a file, including additional useful info 3 | 4 | width=72 5 | 6 | for input 7 | do 8 | lines="$(wc -l < $input | sed 's/ //g')" 9 | chars="$(wc -c < $input | sed 's/ //g')" 10 | owner="$(ls -ld $input | awk '{print $3}')" 11 | echo "-----------------------------------------------------------------" 12 | echo "File $input ($lines lines, $chars characters, owned by $owner):" 13 | echo "-----------------------------------------------------------------" 14 | while read line 15 | do 16 | if [ ${#line} -gt $width ] ; then 17 | echo "$line" | fmt | sed -e '1s/^/ /' -e '2,$s/^/+ /' 18 | else 19 | echo " $line" 20 | fi 21 | done < $input 22 | 23 | echo "-----------------------------------------------------------------" 24 | 25 | done | more 26 | 27 | exit 0 28 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/033-toolong.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # toolong - only feed the fmt command those lines in the input stream 3 | # that are longer than the specified length 4 | 5 | width=72 6 | 7 | if [ ! -r "$1" ] ; then 8 | echo "Usage: $0 filename" >&2; exit 1 9 | fi 10 | 11 | while read input 12 | do 13 | if [ ${#input} -gt $width ] ; then 14 | echo "$input" | fmt 15 | else 16 | echo "$input" 17 | fi 18 | done < $1 19 | 20 | exit 0 21 | 22 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/034-quota.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # newquota - a front-end to quota that works with fullword flags a la GNU 3 | 4 | # quota has three possible flags: -g, -v and -q and in this script 5 | # we allow them to be '--group' '--verbose' and '--quiet' too: 6 | 7 | flags="" 8 | realquota="/usr/bin/quota" 9 | 10 | while [ $# -gt 0 ] 11 | do 12 | echo checking flag $1 13 | case $1 14 | in 15 | --help ) echo "Usage: $0 [--group --verbose --quiet -gvq]" >&2 16 | exit 1 ;; 17 | --group | -group) flags="$flags -g"; shift ;; 18 | --verbose | -verbose) flags="$flags -v"; shift ;; 19 | --quiet | -quiet) flags="$flags -q"; shift ;; 20 | -- ) shift; break ;; 21 | * ) break; # done with 'while' loop! 22 | esac 23 | done 24 | 25 | exec $realquota $flags "$@" 26 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/035-mysftp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # mysftp - make sftp start up more like ftp 4 | 5 | echo -n "User account: " 6 | read account 7 | 8 | if [ -z "$account" ] ; then 9 | exit 0; # changed their mind, presumably 10 | fi 11 | 12 | if [ -z "$1" ] ; then 13 | echo -n "Remote host: " 14 | read host 15 | if [ -z $host ] ; then 16 | exit 0 17 | fi 18 | else 19 | host=$1 20 | fi 21 | 22 | # echo sftp -C $account@$host 23 | 24 | exec /usr/bin/sftp -C $account@$host 25 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/036-cgrep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # cgrep - grep with context display and highlighted pattern matches 4 | 5 | context=0 6 | esc="" 7 | bOn="${esc}[1m" bOff="${esc}[22m" 8 | sedscript="/tmp/cgrep.sed.$$" 9 | tempout="/tmp/cgrep.$$" 10 | 11 | showMatches() 12 | { 13 | matches=0 14 | 15 | echo "s/$pattern/${bOn}$pattern${bOff}/g" > $sedscript 16 | 17 | for lineno in $(grep -n "$pattern" $1 | cut -d: -f1) 18 | do 19 | if [ $context -gt 0 ] ; then 20 | prev="$(( $lineno - $context ))" 21 | if [ "$(echo $prev | cut -c1)" = "-" ] ; then 22 | prev="0" 23 | fi 24 | next="$(( $lineno + $context ))" 25 | 26 | if [ $matches -gt 0 ] ; then 27 | echo "${prev}i\\" >> $sedscript 28 | echo "----" >> $sedscript 29 | fi 30 | echo "${prev},${next}p" >> $sedscript 31 | else 32 | echo "${lineno}p" >> $sedscript 33 | fi 34 | matches="$(( $matches + 1 ))" 35 | done 36 | 37 | if [ $matches -gt 0 ] ; then 38 | sed -n -f $sedscript $1 | uniq | more 39 | fi 40 | } 41 | 42 | trap "/bin/rm -f $tempout $sedscript" EXIT 43 | 44 | if [ -z "$1" ] ; then 45 | echo "Usage: $0 [-c X] pattern {filename}" >&2; exit 0 46 | fi 47 | 48 | if [ "$1" = "-c" ] ; then 49 | context="$2" 50 | shift; shift 51 | elif [ "$(echo $1|cut -c1-2)" = "-c" ] ; then 52 | context="$(echo $1 | cut -c3-)" 53 | shift 54 | fi 55 | 56 | pattern="$1"; shift 57 | 58 | if [ $# -gt 0 ] ; then 59 | for filename ; do 60 | echo "----- $filename -----" 61 | showMatches $filename 62 | done 63 | else 64 | cat - > $tempout # save stream to a temp file 65 | showMatches $tempout 66 | fi 67 | 68 | exit 0 69 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/037-zcat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # zcat, zmore, and zgrep - this script should be either symbolically 4 | # linked or hard linked to all three names - it allows users to work 5 | # with compressed files transparently. 6 | 7 | Z="compress"; unZ="uncompress" ; Zlist="" 8 | gz="gzip" ; ungz="gunzip" ; gzlist="" 9 | bz="bzip2" ; unbz="bunzip2" ; bzlist="" 10 | 11 | # First step is to try and isolate the filenames in the command line 12 | # we'll do this lazily by stepping through each argument testing to 13 | # see if it's a filename or not. If it is, and it has a compression 14 | # suffix, we'll uncompress the file, rewrite the filename, and proceed. 15 | # When done, we'll recompress everything that was uncompressed. 16 | 17 | for arg 18 | do 19 | if [ -f "$arg" ] ; then 20 | case $arg in 21 | *.Z) $unZ "$arg" 22 | arg="$(echo $arg | sed 's/\.Z$//')" 23 | Zlist="$Zlist \"$arg\"" 24 | ;; 25 | 26 | *.gz) $ungz "$arg" 27 | arg="$(echo $arg | sed 's/\.gz$//')" 28 | gzlist="$gzlist \"$arg\"" 29 | ;; 30 | 31 | *.bz2) $unbz "$arg" 32 | arg="$(echo $arg | sed 's/\.bz2$//')" 33 | bzlist="$bzlist \"$arg\"" 34 | ;; 35 | 36 | esac 37 | fi 38 | newargs="${newargs:-""} \"$arg\"" 39 | done 40 | 41 | case $0 in 42 | *zcat* ) eval cat $newargs ;; 43 | *zmore* ) eval more $newargs ;; 44 | *zgrep* ) eval grep $newargs ;; 45 | * ) echo "$0: unknown base name. Can't proceed." >&2; exit 1 46 | esac 47 | 48 | # now recompress everything 49 | 50 | if [ ! -z "$Zlist" ] ; then 51 | eval $Z $Zlist 52 | fi 53 | if [ ! -z "$gzlist" ] ; then 54 | eval $gz $gzlist 55 | fi 56 | if [ ! -z "$bzlist" ] ; then 57 | eval $bz $bzlist 58 | fi 59 | 60 | # and done 61 | 62 | exit 0 63 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/038-bestcompress.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # bestcompress - given a file, try compressing it with all the available 4 | # compression tools and keep the compressed file that's smallest, reporting 5 | # the result to the user. If '-a' isn't specified, it skips compressed 6 | # files in the input stream. 7 | 8 | Z="compress" 9 | gz="gzip" 10 | bz="bzip2" 11 | Zout="/tmp/bestcompress.$$.Z" 12 | gzout="/tmp/bestcompress.$$.gz" 13 | bzout="/tmp/bestcompress.$$.bz" 14 | skipcompressed=1 15 | 16 | if [ "$1" = "-a" ] ; then 17 | skipcompressed=0 ; shift 18 | fi 19 | 20 | if [ $# -eq 0 ]; then 21 | echo "Usage: $0 [-a] file or files to optimally compress" >&2; exit 1 22 | fi 23 | 24 | trap "/bin/rm -f $Zout $gzout $bzout" EXIT 25 | 26 | for name 27 | do 28 | if [ ! -f "$name" ] ; then 29 | echo "$0: file $name not found. Skipped." >&2 30 | continue 31 | fi 32 | 33 | if [ "$(echo $name | egrep '(\.Z$|\.gz$|\.bz2$)')" != "" ] ; then 34 | if [ $skipcompressed -eq 1 ] ; then 35 | echo "Skipped file ${name}: it's already compressed." 36 | continue 37 | else 38 | echo "Warning: Trying to double-compress $name" 39 | fi 40 | fi 41 | 42 | $Z < "$name" > $Zout & 43 | $gz < "$name" > $gzout & 44 | $bz < "$name" > $bzout & 45 | 46 | wait # run compressions in parallel for speed. Wait until all are done 47 | 48 | smallest="$(ls -l "$name" $Zout $gzout $bzout | \ 49 | awk '{print $5"="NR}' | sort -n | cut -d= -f2 | head -1)" 50 | 51 | case "$smallest" in 52 | 1 ) echo "No space savings by compressing $name. Left as-is." 53 | ;; 54 | 2 ) echo Best compression is with compress. File renamed ${name}.Z 55 | mv $Zout "${name}.Z" ; rm -f "$name" 56 | ;; 57 | 3 ) echo Best compression is with gzip. File renamed ${name}.gz 58 | mv $gzout "${name}.gz" ; rm -f "$name" 59 | ;; 60 | 4 ) echo Best compression is with bzip2. File renamed ${name}.bz2 61 | mv $bzout "${name}.bz2" ; rm -f "$name" 62 | esac 63 | 64 | done 65 | 66 | exit 0 67 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/039-fquota.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # FQUOTA - Disk quota analysis tool for Unix. 4 | # Assumes that all user accounts are >= UID 100. 5 | 6 | MAXDISKUSAGE=20 7 | 8 | for name in $(cut -d: -f1,3 /etc/passwd | awk -F: '$2 > 99 { print $1 }') 9 | do 10 | echo -n "User $name exceeds disk quota. Disk usage is: " 11 | 12 | find / /usr /var /Users -user $name -xdev -type f -ls | \ 13 | awk '{ sum += $7 } END { print sum / (1024*1024) " Mbytes" }' 14 | 15 | done | awk "\$9 > $MAXDISKUSAGE { print \$0 }" 16 | 17 | exit 0 18 | 19 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/040-diskhogs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # DISKHOGS - Disk quota analysis tool for Unix, assumes all user 4 | # accounts are >= UID 100. Emails message to each violating user 5 | # and reports a summary to the screen 6 | 7 | MAXDISKUSAGE=20 8 | violators="/tmp/diskhogs0.$$" 9 | 10 | trap "/bin/rm -f $violators" 0 11 | 12 | for name in $(cut -d: -f1,3 /etc/passwd | awk -F: '$2 > 99 { print $1 }') 13 | do 14 | echo -n "$name " 15 | 16 | find / /usr /var /Users -user $name -xdev -type f -ls | \ 17 | awk '{ sum += $7 } END { print sum / (1024*1024) }' 18 | 19 | done | awk "\$2 > $MAXDISKUSAGE { print \$0 }" > $violators 20 | 21 | if [ ! -s $violators ] ; then 22 | echo "No users exceed the disk quota of ${MAXDISKUSAGE}MB" 23 | cat $violators 24 | exit 0 25 | fi 26 | 27 | while read account usage ; do 28 | 29 | cat << EOF | fmt | mail -s "Warning: $account Exceeds Quota" $account 30 | Your disk usage is ${usage}MB but you have only been allocated 31 | ${MAXDISKUSAGE}MB. This means that either you need to delete some of 32 | your files, compress your files (see 'gzip' or 'bzip2' for powerful and 33 | easy-to-use compression programs), or talk with us about increasing 34 | your disk allocation. 35 | 36 | Thanks for your cooperation on this matter. 37 | 38 | Dave Taylor @ x554 39 | EOF 40 | 41 | echo "Account $account has $usage MB of disk space. User notified." 42 | 43 | done < $violators 44 | 45 | exit 0 46 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/041-diskspace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # diskspace - summarize available disk space and present in a logical 4 | # and readable fashion 5 | 6 | tempfile="/tmp/available.$$" 7 | 8 | trap "rm -f $tempfile" EXIT 9 | 10 | cat << 'EOF' > $tempfile 11 | { sum += $4 } 12 | END { mb = sum / 1024 13 | gb = mb / 1024 14 | printf "%.0f MB (%.2fGB) of available disk space\n", mb, gb 15 | } 16 | EOF 17 | 18 | df -k | awk -f $tempfile 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/042-newdf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # newdf - a friendlier version of df 4 | 5 | sedscript="/tmp/newdf.$$" 6 | 7 | trap "rm -f $sedscript" EXIT 8 | 9 | cat << 'EOF' > $sedscript 10 | function showunit(size) 11 | { mb = size / 1024; prettymb=(int(mb * 100)) / 100; 12 | gb = mb / 1024; prettygb=(int(gb * 100)) / 100; 13 | 14 | if ( substr(size,1,1) !~ "[0-9]" || 15 | substr(size,2,1) !~ "[0-9]" ) { return size } 16 | else if ( mb < 1) { return size "K" } 17 | else if ( gb < 1) { return prettymb "M" } 18 | else { return prettygb "G" } 19 | } 20 | 21 | BEGIN { 22 | printf "%-27s %7s %7s %7s %8s %-s\n", 23 | "Filesystem", "Size", "Used", "Avail", "Capacity", "Mounted" 24 | } 25 | 26 | !/Filesystem/ { 27 | 28 | size=showunit($2); 29 | used=showunit($3); 30 | avail=showunit($4); 31 | 32 | printf "%-27s %7s %7s %7s %8s %-s\n", 33 | $1, size, used, avail, $5, $6 34 | } 35 | EOF 36 | 37 | df -k | awk -f $sedscript 38 | 39 | exit 0 40 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/043-mkslocate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # mkslocatedb - build the central, public locate database as user nobody, 4 | # and simultaneously step through each home directory to find those 5 | # that contain a .slocatedb file. If found, an additional, private 6 | # version of the locate database will be created for that user. 7 | 8 | locatedb="/var/locate.db" 9 | slocatedb=".slocatedb" 10 | 11 | if [ "$(whoami)" != "root" ] ; then 12 | echo "$0: Error: You must be root to run this command." >&2 13 | exit 1 14 | fi 15 | 16 | if [ "$(grep '^nobody:' /etc/passwd)" = "" ] ; then 17 | echo "$0: Error: you must have an account for user 'nobody'" >&2 18 | echo "to create the default slocate database." >&2; exit 1 19 | fi 20 | 21 | cd / # sidestep post-su pwd permission problems 22 | 23 | # first, create or update the public database 24 | su -fm nobody -c "find / -print" > $locatedb 2>/dev/null 25 | echo "building default slocate database (user = nobody)" 26 | echo ... result is $(wc -l < $locatedb) lines long. 27 | 28 | 29 | # now step through the user accounts on the system to see who has 30 | # a $slocatedb file in their home directory.... 31 | 32 | for account in $(cut -d: -f1 /etc/passwd) 33 | do 34 | homedir="$(grep "^${account}:" /etc/passwd | cut -d: -f6)" 35 | 36 | if [ "$homedir" = "/" ] ; then 37 | continue # refuse to build one for root dir 38 | elif [ -e $homedir/$slocatedb ] ; then 39 | echo "building slocate database for user $account" 40 | su -fm $account -c "find / -print" > $homedir/$slocatedb \ 41 | 2>/dev/null 42 | chmod 600 $homedir/$slocatedb 43 | chown $account $homedir/$slocatedb 44 | echo ... result is $(wc -l < $homedir/$slocatedb) lines long. 45 | fi 46 | done 47 | 48 | exit 0 49 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/043-slocate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # slocate - Try to search the user's secure locate database for the 4 | # specified pattern. If none exists, output a warning and create 5 | # one. If secure locate db is empty, use system one instead. 6 | 7 | locatedb="/var/locate.db" 8 | slocatedb="$HOME/.slocatedb" 9 | 10 | if [ "$1" = "--explain" ] ; then 11 | cat << "EOF" >&2 12 | Warning: Secure locate keeps a private database for each user, and your 13 | database hasn't yet been created. Until it is (probably late tonight) 14 | I'll just use the public locate database, which will show you all 15 | publicly accessible matches, rather than those explicitly available to 16 | account ${USER:-$LOGNAME}. 17 | EOF 18 | if [ "$1" = "--explain" ] ; then 19 | exit 0 20 | fi 21 | 22 | # before we go, create a .slocatedb so that cron will fill it 23 | # the next time the mkslocatedb script is run 24 | 25 | touch $slocatedb # mkslocatedb will build it next time through 26 | chmod 600 $slocatedb # start on the right foot with permissions 27 | 28 | elif [ -s $slocatedb ] ; then 29 | locatedb=$slocatedb 30 | else 31 | echo "Warning: using public database. Use \"$0 --explain\" for details." >&2 32 | fi 33 | 34 | if [ -z "$1" ] ; then 35 | echo "Usage: $0 pattern" >&2; exit 1 36 | fi 37 | 38 | exec grep -i "$1" $locatedb 39 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/044-adduser.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # ADDUSER - add a new user to the system, including building their 4 | # home directory, copying in default config data, etc. 5 | # For a standard Unix/Linux system, not Mac OS X 6 | 7 | pwfile="/etc/passwd" shadowfile="/etc/shadow" 8 | gfile="/etc/group" 9 | hdir="/home" 10 | 11 | if [ "$(whoami)" != "root" ] ; then 12 | echo "Error: You must be root to run this command." >&2 13 | exit 1 14 | fi 15 | 16 | echo "Add new user account to $(hostname)" 17 | echo -n "login: " ; read login 18 | 19 | # adjust '5000' to match the top end of your user account namespace 20 | # because some system accounts have uid's like 65535 and similar. 21 | 22 | uid="$(awk -F: '{ if (big < $3 && $3 < 5000) big=$3 } END { print big + 1 }' $pwfile)" 23 | homedir=$hdir/$login 24 | 25 | # we are giving each user their own group, so gid=uid 26 | gid=$uid 27 | 28 | echo -n "full name: " ; read fullname 29 | echo -n "shell: " ; read shell 30 | 31 | echo "Setting up account $login for $fullname..." 32 | 33 | echo ${login}:x:${uid}:${gid}:${fullname}:${homedir}:$shell >> $pwfile 34 | echo ${login}:*:11647:0:99999:7::: >> $shadowfile 35 | 36 | echo "${login}:x:${gid}:$login" >> $gfile 37 | 38 | mkdir $homedir 39 | cp -R /etc/skel/.[a-zA-Z]* $homedir 40 | chmod 755 $homedir 41 | find $homedir -print | xargs chown ${login}:$login 42 | 43 | # setting an initial password 44 | passwd $login 45 | 46 | exit 0 47 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/045-suspenduser.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ## Suspend - suspend a user account for the indefinite future 4 | 5 | homedir="/home" # home directory for users 6 | secs=10 # seconds before user is logged out 7 | 8 | if [ -z $1 ] ; then 9 | echo "Usage: $0 account" >&2 ; exit 1 10 | elif [ "$(whoami)" != "root" ] ; then 11 | echo "Error. You must be 'root' to run this command." >&2; exit 1 12 | fi 13 | 14 | echo "Please change account $1 password to something new." 15 | passwd $1 16 | 17 | # Now, let's see if they're logged in, and if so, boot 'em 18 | 19 | if [ ! -z $(who | grep $1) ] ; then 20 | 21 | tty="$(who | grep $1 | tail -1 | awk '{print $2}')" 22 | 23 | cat << "EOF" > /dev/$tty 24 | 25 | ************************************************************* 26 | URGENT NOTICE FROM THE ADMINISTRATOR: 27 | 28 | This account is being suspended at the request of management. 29 | You are going to be logged out in $secs seconds. Please immediately 30 | shut down any processes you have running and log out. 31 | 32 | If you have any questions, please contact your supervisor or 33 | John Doe, Director of Information Technology. 34 | ************************************************************* 35 | EOF 36 | 37 | echo "(Warned $1, now sleeping $secs seconds)" 38 | 39 | sleep $secs 40 | 41 | killall -s HUP -u $1 # send hangup sig to their processes 42 | sleep 1 # give it a second... 43 | killall -s KILL -u $1 # and kill anything left 44 | 45 | echo "$(date): $1 was logged in. Just logged them out." 46 | fi 47 | 48 | # Finally, let's close off their home directory from prying eyes: 49 | 50 | chmod 000 $homedir/$1 51 | 52 | echo "Account $1 has been suspended." 53 | 54 | exit 0 55 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/046-deleteuser.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ## Delete - delete a user account without a trace... 4 | # Not for use with Mac OS X 5 | 6 | homedir="/home" 7 | pwfile="/etc/passwd" shadow="/etc/shadow" 8 | newpwfile="/etc/passwd.new" newshadow="/etc/shadow.new" 9 | suspend="echo suspending " 10 | locker="/etc/passwd.lock" 11 | 12 | if [ -z $1 ] ; then 13 | echo "Usage: $0 account" >&2; exit 1 14 | elif [ "$(whoami)" != "root" ] ; then 15 | echo "Error: you must be 'root' to run this command.">&2; exit 1 16 | fi 17 | 18 | # $suspend $1 # suspend their account while we do the dirty work 19 | 20 | uid="$(grep -E "^${1}:" $pwfile | cut -d: -f3)" 21 | 22 | if [ -z $uid ] ; then 23 | echo "Error: no account $1 found in $pwfile" >&2; exit 1 24 | fi 25 | 26 | # remove from the password and shadow files 27 | grep -vE "^${1}:" $pwfile > $newpwfile 28 | grep -vE "^${1}:" $shadow > $newshadow 29 | 30 | lockcmd="$(which lockfile)" # find it in the path 31 | if [ ! -z $lockcmd ] ; then # let's use the system lockfile 32 | eval $lockcmd -r 15 $locker 33 | else # ulp, let's do it ourselves 34 | while [ -e $locker ] ; do 35 | echo "waiting for the password file" ; sleep 1 36 | done 37 | touch $locker # created a file-based lock 38 | fi 39 | 40 | mv $newpwfile $pwfile 41 | mv $newshadow $shadow 42 | rm -f $locker # click! unlocked again 43 | 44 | chmod 644 $pwfile 45 | chmod 400 $shadow 46 | 47 | # now remove home directory and list anything left... 48 | rm -rf $homedir/$1 49 | 50 | echo "Files still left to remove (if any):" 51 | find / -uid $uid -print 2>/dev/null | sed 's/^/ /' 52 | 53 | echo "" 54 | echo "Account $1 (uid $uid) has been deleted, and their home directory " 55 | echo "($homedir/$1) has been removed." 56 | 57 | exit 0 58 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/048-fixguest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # fixguest - Clean up the guest account during the logout process 4 | 5 | # don't trust environment variables: reference read-only sources 6 | 7 | iam="$(whoami)" 8 | myhome="$(grep "^${iam}:" /etc/passwd | cut -d: -f6)" 9 | 10 | # *** Do NOT run this script on a regular user account! 11 | 12 | if [ "$iam" != "guest" ] ; then 13 | echo "Error: you really don't want to run fixguest on this account." >&2 14 | exit 1 15 | fi 16 | 17 | if [ ! -d $myhome/..template ] ; then 18 | echo "$0: no template directory found for rebuilding." >&2 19 | exit 1 20 | fi 21 | 22 | # remove all files and directories in the home account 23 | 24 | cd $myhome 25 | 26 | rm -rf * $(find . -name ".[a-zA-Z0-9]*" -print) 27 | 28 | # now the only thing present should be the ..template directory 29 | 30 | cp -Rp ..template/* . 31 | 32 | exit 0 33 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/049-findsuid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # findsuid - find all SUID files or programs on the system other 4 | # than those that live in /bin and /usr/bin, and 5 | # output the matches in a friendly and useful format. 6 | 7 | mtime="7" # how far back (in days) to check for modified cmds 8 | verbose=0 # by default, let's be quiet about things 9 | 10 | if [ "$1" = "-v" ] ; then 11 | verbose=1 12 | fi 13 | 14 | for match in $(find /bin /usr/bin -type f -perm +4000 -print) 15 | do 16 | if [ -x $match ] ; then 17 | 18 | owner="$(ls -ld $match | awk '{print $3}')" 19 | perms="$(ls -ld $match | cut -c5-10 | grep 'w')" 20 | 21 | if [ ! -z $perms ] ; then 22 | echo "**** $match (writeable and setuid $owner)" 23 | elif [ ! -z $(find $match -mtime -$mtime -print) ] ; then 24 | echo "**** $match (modified within $mtime days and setuid $owner)" 25 | elif [ $verbose -eq 1 ] ; then 26 | lastmod="$(ls -ld $match | awk '{print $6, $7, $8}')" 27 | echo " $match (setuid $owner, last modified $lastmod)" 28 | fi 29 | fi 30 | done 31 | 32 | exit 0 33 | 34 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/050-set-date.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # setdate - friendly front-end to the date command 3 | 4 | # Date wants: [[[[[cc]yy]mm]dd]hh]mm[.ss] 5 | 6 | askvalue() 7 | { 8 | # $1 = field name, $2 = default value, $3 = max value, 9 | # $4 = required char/digit length 10 | 11 | echo -n "$1 [$2] : " 12 | read answer 13 | if [ ${answer:=$2} -gt $3 ] ; then 14 | echo "$0: $1 $answer is invalid"; exit 0 15 | elif [ "$(( $(echo $answer | wc -c) - 1 ))" -lt $4 ] ; then 16 | echo "$0: $1 $answer is too short: please specify $4 digits"; exit 0 17 | fi 18 | eval $1=$answer 19 | } 20 | 21 | eval $(date "+nyear=%Y nmon=%m nday=%d nhr=%H nmin=%M") 22 | 23 | askvalue year $nyear 3000 4 24 | askvalue month $nmon 12 2 25 | askvalue day $nday 31 2 26 | askvalue hour $nhr 24 2 27 | askvalue minute $nmin 59 2 28 | 29 | squished="$year$month$day$hour$minute" 30 | # or, if you're running a Linux system: 31 | # squished="$month$day$hour$minute$year" 32 | 33 | echo "Setting date to $squished. You might need to enter your sudo password:" 34 | sudo date $squished 35 | 36 | exit 0 37 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/051-enabled.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # enabled - show what services are enabled with inetd and xinetd, 4 | # if they're available on the system. 5 | 6 | iconf="/etc/inetd.conf" 7 | xconf="/etc/xinetd.conf" 8 | xdir="/etc/xinetd.d" 9 | 10 | if [ -r $iconf ] ; then 11 | echo "Services enabled in $iconf are:" 12 | grep -v '^#' $iconf | awk '{print " " $1}' 13 | echo "" 14 | if [ "$(ps -aux | grep inetd | egrep -vE '(xinet|grep)')" = "" ] ; then 15 | echo "** warning: inetd does not appear to be running" 16 | fi 17 | fi 18 | 19 | if [ -r $xconf ] ; then 20 | # don't need to look in xinietd.conf, just know it exists 21 | echo "Services enabled in $xdir are:" 22 | 23 | for service in $xdir/* 24 | do 25 | if ! $(grep disable $service | grep 'yes' > /dev/null) ; then 26 | echo -n " " 27 | basename $service 28 | fi 29 | done 30 | 31 | if ! $(ps -aux | grep xinetd | grep -v 'grep' > /dev/null) ; then 32 | echo "** warning: xinetd does not appear to be running" 33 | fi 34 | fi 35 | 36 | exit 0 37 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/052-killall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # killall - send the specified signal to all processes that match a 4 | # specific process name 5 | 6 | # By default it only kills processes owned by the same user, unless 7 | # you're root. Use -s SIGNAL to specify a signal to send, -u user to 8 | # specify user, -t tty to specify a tty, and -n to only show what'd 9 | # be done rather than doing it 10 | 11 | signal="-INT" # default signal 12 | user="" tty="" donothing=0 13 | 14 | while getopts "s:u:t:n" opt; do 15 | case "$opt" in 16 | # note the trick below: kill wants -SIGNAL but we're asking 17 | # for SIGNAL, so we slip the '-' in as part of the assignment 18 | s ) signal="-$OPTARG"; ;; 19 | u ) if [ ! -z "$tty" ] ; then 20 | echo "$0: error: -u and -t are mutually exclusive." >&2 21 | exit 1 22 | fi 23 | user=$OPTARG; ;; 24 | t ) if [ ! -z "$user" ] ; then 25 | echo "$0: error: -u and -t are mutually exclusive." >&2 26 | exit 1 27 | fi 28 | tty=$2; ;; 29 | n ) donothing=1; ;; 30 | ? ) echo "Usage: $0 [-s signal] [-u user|-t tty] [-n] pattern" >&2 31 | exit 1 32 | esac 33 | done 34 | 35 | shift $(( $OPTIND - 1 )) 36 | 37 | if [ $# -eq 0 ] ; then 38 | echo "Usage: $0 [-s signal] [-u user|-t tty] [-n] pattern" >&2 39 | exit 1 40 | fi 41 | 42 | if [ ! -z "$tty" ] ; then 43 | pids=$(ps cu -t $tty | awk "/ $1$/ { print \$2 }") 44 | elif [ ! -z "$user" ] ; then 45 | pids=$(ps cu -U $user | awk "/ $1$/ { print \$2 }") 46 | else 47 | pids=$(ps cu -U ${USER:-LOGNAME} | awk "/ $1$/ { print \$2 }") 48 | fi 49 | 50 | if [ -z "$pids" ] ; then 51 | echo "$0: no processes match pattern $1" >&2; exit 1 52 | fi 53 | 54 | for pid in $pids 55 | do 56 | # Sending signal $signal to process id $pid: kill might 57 | # still complain if the process has finished, user doesn't 58 | # have permission, etc, but that's okay. 59 | if [ $donothing -eq 1 ] ; then 60 | echo "kill $signal $pid" 61 | else 62 | kill $signal $pid 63 | fi 64 | done 65 | 66 | exit 0 67 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/054-docron.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # DOCRON - simple script to run the daily, weekly and monthly 4 | # system cron jobs on a system where it's likely that 5 | # it'll be shut down at the usual time of day when 6 | # this would occur. 7 | 8 | rootcron="/etc/crontab" 9 | 10 | if [ $# -ne 1 ] ; then 11 | echo "Usage: $0 [daily|weekly|monthly]" >&2 12 | exit 1 13 | fi 14 | 15 | if [ "$(id -u)" -ne 0 ] ; then 16 | echo "$0: Command must be run as 'root'" >&2 17 | exit 1 18 | fi 19 | 20 | job="$(awk "NR > 6 && /$1/ { for (i=7;i<=NF;i++) print \$i }" $rootcron)" 21 | 22 | if [ -z $job ] ; then 23 | echo "$0: Error: no $1 job found in $rootcron" >&2 24 | exit 1 25 | fi 26 | 27 | SHELL=/bin/sh # to be consistent with cron's default 28 | 29 | eval $job 30 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/056-backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Backup - create either a full or incremental backup of a set of 4 | # defined directories on the system. By default, the output 5 | # file is saved in /tmp with a timestamped filename, compressed. 6 | # Otherwise, specify an output device (another disk, a removable). 7 | 8 | usageQuit() 9 | { 10 | cat << "EOF" >&2 11 | Usage: $0 [-o output] [-i|-f] [-n] 12 | -o lets you specify an alternative backup file/device 13 | -i is an incremental or -f is a full backup, and -n prevents 14 | updating the timestamp if an incremental backup is done. 15 | EOF 16 | exit 1 17 | } 18 | 19 | compress="bzip2" # change for your favorite compression app 20 | inclist="/tmp/backup.inclist.$(date +%d%m%y)" 21 | output="/tmp/backup.$(date +%d%m%y).bz2" 22 | tsfile="$HOME/.backup.timestamp" 23 | btype="incremental" # default to an incremental backup 24 | noinc=0 # and an update of the timestamp 25 | 26 | trap "/bin/rm -f $inclist" EXIT 27 | 28 | while getopts "o:ifn" opt; do 29 | case "$arg" in 30 | o ) output="$OPTARG"; ;; 31 | i ) btype="incremental"; ;; 32 | f ) btype="full"; ;; 33 | n ) noinc=1; ;; 34 | ? ) usageQuit ;; 35 | esac 36 | done 37 | 38 | shift $(( $OPTIND - 1 )) 39 | 40 | echo "Doing $btype backup, saving output to $output" 41 | 42 | timestamp="$(date +'%m%d%I%M')" 43 | 44 | if [ "$btype" = "incremental" ] ; then 45 | if [ ! -f $tsfile ] ; then 46 | echo "Error: can't do an incremental backup: no timestamp file" >&2 47 | exit 1 48 | fi 49 | find $HOME -depth -type f -newer $tsfile -user ${USER:-LOGNAME} | \ 50 | pax -w -x tar | $compress > $output 51 | failure="$?" 52 | else 53 | find $HOME -depth -type f -user ${USER:-LOGNAME} | \ 54 | pax -w -x tar | $compress > $output 55 | failure="$?" 56 | fi 57 | 58 | if [ "$noinc" = "0" -a "$failure" = "0" ] ; then 59 | touch -t $timestamp $tsfile 60 | fi 61 | 62 | exit 0 63 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/057-archivedir.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # archivedir - create a compressed archive of the specified directory 4 | 5 | maxarchivedir=10 # size, in blocks, of 'big' directory, to confirm 6 | compress=gzip # change to your favorite compress app 7 | progname=$(basename $0) 8 | 9 | if [ $# -eq 0 ] ; then 10 | echo "Usage: $progname directory" >&2 ;exit 1 11 | fi 12 | 13 | if [ ! -d $1 ] ; then 14 | echo "${progname}: can't find directory $1 to archive." >&2; exit 1 15 | fi 16 | 17 | if [ "$(basename $1)" != "$1" -o "$1" = "." ] ; then 18 | echo "${progname}: You must specify a subdirectory" >&2 19 | exit 1 20 | fi 21 | 22 | if [ ! -w . ] ; then 23 | echo "${progname}: cannot write archive file to current directory." >&2 24 | exit 1 25 | fi 26 | 27 | dirsize="$(du -s $1 | awk '{print $1}')" 28 | 29 | if [ $dirsize -gt $maxarchivedir ] ; then 30 | echo -n "Warning: directory $1 is $dirsize blocks. Proceed? [n] " 31 | read answer 32 | answer="$(echo $answer | tr '[:upper:]' '[:lower:]' | cut -c1)" 33 | if [ "$answer" != "y" ] ; then 34 | echo "${progname}: archive of directory $1 cancelled." >&2 35 | exit 0 36 | fi 37 | fi 38 | 39 | archivename="$(echo $1 | sed 's/$/.tgz/')" 40 | 41 | if tar cf - $1 | $compress > $archivename ; then 42 | echo "Directory $1 archived as $archivename" 43 | else 44 | echo "Warning: tar encountered errors archiving $1" 45 | fi 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/058-connecttime.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # connecttime - reports cumulative connection time for month/year entries 4 | # found in the system log file. 5 | 6 | log="/var/log/system.log" 7 | tempfile="/tmp/$0.$$" 8 | 9 | trap "rm $tempfile" 0 10 | 11 | cat << 'EOF' > $tempfile 12 | BEGIN { 13 | lastmonth=""; sum = 0 14 | } 15 | { 16 | if ( $1 != lastmonth && lastmonth != "" ) { 17 | if (sum > 60) { total = sum/60 " hours" } 18 | else { total = sum " minutes" } 19 | print lastmonth ": " total 20 | sum=0 21 | } 22 | lastmonth=$1 23 | sum += $8 24 | } 25 | END { 26 | if (sum > 60) { total = sum/60 " hours" } 27 | else { total = sum " minutes" } 28 | print lastmonth ": " total 29 | } 30 | EOF 31 | 32 | grep "Connect time" $log | awk -f $tempfile 33 | 34 | exit 0 35 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/059-ftpget.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # ftpget - given an ftp: style URL, unwrap it, and try to obtain the file 4 | # using anonymous ftp. 5 | 6 | anonpass="$LOGNAME@$(hostname)" 7 | 8 | if [ $# -ne 1 ] ; then 9 | echo "Usage: $0 ftp://..." >&2 10 | exit 1 11 | fi 12 | 13 | # Typical URL: ftp://ftp.ncftp.com/2.7.1/ncftpd-2.7.1.tar.gz 14 | 15 | if [ "$(echo $1 | cut -c1-6)" != "ftp://" ] ; then 16 | echo "$0: Malformed url. I need it to start with ftp://" >&2; 17 | exit 1 18 | fi 19 | 20 | server="$(echo $1 | cut -d/ -f3)" 21 | filename="$(echo $1 | cut -d/ -f4-)" 22 | basefile="$(basename $filename)" 23 | 24 | echo ${0}: Downloading $basefile from server $server 25 | 26 | ftp -n << EOF 27 | open $server 28 | user ftp $anonpass 29 | get $filename $basefile 30 | quit 31 | EOF 32 | 33 | if [ $? -eq 0 ] ; then 34 | ls -l $basefile 35 | fi 36 | 37 | exit 0 38 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/060-bbcnews.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # bbcnews - report the top stories on the BBC World Service 4 | 5 | url="http://news.bbc.co.uk/2/low/technology/default.stm" 6 | 7 | lynx -source $url | \ 8 | sed -n '/Last Updated:/,/newssearch.bbc.co.uk/p' | \ 9 | sed 's//>\ 11 | /g' | \ 12 | grep -v -E '(<|>)' | \ 13 | fmt | \ 14 | uniq 15 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/061-getlinks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # getlinks - given a URL, return all of its internal and 4 | # external links 5 | 6 | if [ $# -eq 0 ] ; then 7 | echo "Usage: $0 [-d|-i|-x] url" >&2 8 | echo "-d=domains only, -i=internal refs only, -x=external only" >&2 9 | exit 1 10 | fi 11 | 12 | if [ $# -gt 1 ] ; then 13 | case "$1" in 14 | -d) lastcmd="cut -d/ -f3 | sort | uniq" 15 | shift 16 | ;; 17 | -i) basedomain="http://$(echo $2 | cut -d/ -f3)/" 18 | lastcmd="grep \"^$basedomain\" | sed \"s|$basedomain||g\" | sort | uniq" 19 | shift 20 | ;; 21 | -x) basedomain="http://$(echo $2 | cut -d/ -f3)/" 22 | lastcmd="grep -v \"^$basedomain\" | sort | uniq" 23 | shift 24 | ;; 25 | *) echo "$0: unknown option specified: $1" >&2; exit 1 26 | esac 27 | else 28 | lastcmd="sort | uniq" 29 | fi 30 | 31 | lynx -dump "$1" | \ 32 | sed -n '/^References$/,$p' | \ 33 | grep -E '[[:digit:]]+\.' | \ 34 | awk '{print $2}' | \ 35 | cut -d\? -f1 | \ 36 | eval $lastcmd 37 | 38 | exit 0 39 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/062-define.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # define - given a word, return its definition from dictionary.com 4 | 5 | url="http://www.cogsci.princeton.edu/cgi-bin/webwn1.7.1?stage=1&word=" 6 | 7 | if [ $# -ne 1 ] ; then 8 | echo "Usage: $0 word" >&2 9 | exit 1 10 | fi 11 | 12 | lynx -source "$url$1" | \ 13 | grep -E '(^[[:digit:]]+\.| has [[:digit:]]+$)' | \ 14 | sed 's/<[^>]*>//g' | 15 | ( while read line 16 | do 17 | if [ "${line:0:3}" = "The" ] ; then 18 | part="$(echo $line | awk '{print $2}')" 19 | echo "" 20 | echo "The $part $1:" 21 | else 22 | echo "$line" | fmt | sed 's/^/ /g' 23 | fi 24 | done 25 | ) 26 | 27 | exit 0 28 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/063-weather.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # weather - report weather forecast, including lat/long, for zip 4 | 5 | llurl="http://www.census.gov/cgi-bin/gazetteer?city=&state=&zip=" 6 | wxurl="http://wwwa.accuweather.com" 7 | wxurl="$wxurl/adcbin/public/local_index_print.asp?zipcode=" 8 | 9 | if [ "$1" = "-a" ] ; then 10 | size=999; shift 11 | else 12 | size=5 13 | fi 14 | 15 | if [ $# -eq 0 ] ; then 16 | echo "Usage: $0 [-a] zipcode" >&2 17 | exit 1 18 | fi 19 | 20 | if [ $size -eq 5 ] ; then 21 | echo "" 22 | 23 | # get some information on the zipcode from the Census Bureau 24 | 25 | lynx -source "${llurl}$1" | \ 26 | sed -n '/^
  • /,/^Location:/p' | \ 27 | sed 's/<[^>]*>//g;s/^ //g' 28 | fi 29 | 30 | # the weather forecast itself at accuweather.com 31 | 32 | lynx -source "${wxurl}$1" | \ 33 | sed -n '//,/[^[:digit:]]<\/font>/p' | \ 34 | sed 's/<[^>]*>//g;s/^ [ ]*//g' | \ 35 | uniq | \ 36 | head -$size 37 | 38 | exit 0 39 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/064-checklibrary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # check library - log in to the Boulder Public library computer 4 | # system and show the due date of everything checked out for 5 | # the specified user. A demonstration of how to work with the 6 | # method="post" form with lynx. 7 | 8 | lib1="http://nell.boulder.lib.co.us/patroninfo" 9 | lib2="items" 10 | libacctdb="$HOME/.library.account.info" 11 | postdata="/tmp/$(basename $0).$$" 12 | awkdata="/tmp/$(basename $0).awk.$$" 13 | 14 | # We need: name cardno recordno 15 | # Given the first, look for the other two in the libraryaccount database 16 | 17 | if [ $# -eq 0 ] ; then 18 | echo "Usage: $(basename $0) \"card holder\""; exit 0 19 | fi 20 | 21 | acctinfo="$(grep -i "$1" $libacctdb)" 22 | name="$(echo $acctinfo | cut -d: -f1 | sed 's/ /+/g')" 23 | cardno="$(echo $acctinfo | cut -d: -f2)" 24 | recordno="$(echo $acctinfo | cut -d: -f3)" 25 | 26 | if [ -z "$acctinfo" ] ; then 27 | echo "Problem: account \"$1\" not found in library account database." 28 | exit 1 29 | elif [ $(grep -i "$1" $libacctdb | wc -l) -gt 1 ] ; then 30 | echo "Problem: account \"$1\" matches more than one record in library db." 31 | exit 1 32 | elif [ -z "$cardno" -o -z "$recordno" ] ; then 33 | echo "Problem: card or record information corrupted in database." 34 | exit 1 35 | fi 36 | 37 | trap "/bin/rm -f $postdata $awkdata" 0 38 | 39 | cat << EOF > $postdata 40 | name=${name}&code=${cardno}&submit=Display+record+for+person+named+above 41 | EOF 42 | 43 | cat << "EOF" > $awkdata 44 | { if ( NR % 3 == 1) { title=$0 } 45 | if ( NR % 3 == 2) { print $0 "|" title } 46 | } 47 | EOF 48 | 49 | lynx -source -post-data "$lib1/$recordno/$lib2" < $postdata | \ 50 | grep -E '(^]*>//g' | \ 52 | awk -f $awkdata | sort 53 | 54 | exit 0 55 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/065-moviedata.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # moviedata - given a movie title, return a list of matches, if 4 | # there's more than one, or a synopsis of the movie if there's 5 | # just one. Uses the Internet Movie Database (imdb.com) 6 | 7 | imdburl="http://us.imdb.com/Tsearch?restrict=Movies+only&title=" 8 | titleurl="http://us.imdb.com/Title?" 9 | tempout="/tmp/moviedata.$$" 10 | 11 | summarize_film() 12 | { 13 | # produce an attractive synopsis of the film 14 | 15 | grep "^" $tempout | sed 's/<[^>]*>//g;s/(more)//' 16 | grep '<b class="ch">Plot Outline:</b>' $tempout | \ 17 | sed 's/<[^>]*>//g;s/(more)//;s/(view trailer)//' |fmt|sed 's/^/ /' 18 | exit 0 19 | } 20 | 21 | trap "rm -f $tempout" 0 1 15 22 | 23 | if [ $# -eq 0 ] ; then 24 | echo "Usage: $0 {movie title | movie ID}" >&2 25 | exit 1 26 | fi 27 | 28 | fixedname="$(echo $@ | tr ' ' '+')" # for the URL 29 | 30 | if [ $# -eq 1 ] ; then 31 | nodigits="$(echo $1 | sed 's/[[:digit:]]*//g')" 32 | if [ -z "$nodigits" ] ; then 33 | lynx -source "$titleurl$fixedname" > $tempout 34 | summarize_film 35 | fi 36 | fi 37 | 38 | url="$imdburl$fixedname" 39 | 40 | lynx -source $url > $tempout 41 | 42 | if [ ! -z "$(grep "IMDb title search" $tempout)" ] ; then 43 | grep 'HREF="/Title?' $tempout | \ 44 | sed 's/<OL><LI><A HREF="//;s/<\/A><\/LI>//;s/<LI><A HREF="//' | \ 45 | sed 's/">/ -- /;s/<.*//;s/\/Title?//' | \ 46 | sort -u | \ 47 | more 48 | else 49 | summarize_film 50 | fi 51 | 52 | exit 0 53 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/066-exchangerate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # exchangerate - given a currency amount, convert it into other major 4 | # currencies and show the equivalent amounts in each. 5 | 6 | # ref URL: http://www.ny.frb.org/pihome/statistics/forex12.shtml 7 | 8 | showrate() 9 | { 10 | dollars="$(echo $1 | cut -d. -f1)" 11 | cents="$(echo $1 | cut -d. -f2 | cut -c1-2)" 12 | rate="$dollars.${cents:-00}" 13 | } 14 | 15 | exchratefile="/tmp/.exchangerate" 16 | scriptbc="scriptbc -p 30" # tweak this setting as needed 17 | 18 | . $exchratefile 19 | 20 | # The 0.0000000001 compensates for a rounding error bug in 21 | # many versions of bc, where 1 != 0.99999999999999 22 | 23 | useuro="$($scriptbc 1 / $euro + 0.000000001)" 24 | uscand="$($scriptbc 1 / $canada + 0.000000001)" 25 | usyen="$($scriptbc 1 / $japan + 0.000000001)" 26 | uspound="$($scriptbc 1 / $uk + 0.000000001)" 27 | 28 | if [ $# -ne 2 ] ; then 29 | echo "Usage: $(basename $0) amount currency" 30 | echo "Where currency can be USD, Euro, Canadian, Yen, or Pound." 31 | exit 0 32 | fi 33 | 34 | amount=$1 35 | currency="$(echo $2 | tr '[:upper:]' '[:lower:]' | cut -c1-2)" 36 | 37 | case $currency in 38 | us|do ) if [ -z "$(echo $1 | grep '\.')" ] ; then 39 | masterrate="$1.00" 40 | else 41 | masterrate="$1" 42 | fi ;; 43 | eu ) masterrate="$($scriptbc $1 \* $euro)" ;; 44 | ca|cd ) masterrate="$($scriptbc $1 \* $canada)" ;; 45 | ye ) masterrate="$($scriptbc $1 \* $japan)" ;; 46 | po|st ) masterrate="$($scriptbc $1 \* $uk)" ;; 47 | * ) echo "$0: unknown currency specified." 48 | echo "I only know USD, EURO, CAND/CDN, YEN and GBP/POUND." 49 | exit 1 50 | esac 51 | 52 | echo "Currency Exchange Rate Equivalents for $1 ${2}:" 53 | showrate $masterrate 54 | echo " US Dollars: $rate" 55 | showrate $($scriptbc $masterrate \* $useuro) 56 | echo " EC Euros: $rate" 57 | showrate $($scriptbc $masterrate \* $uscand) 58 | echo "Canadian Dollars: $rate" 59 | showrate $($scriptbc $masterrate \* $usyen) 60 | echo " Japanese Yen: $rate" 61 | showrate $($scriptbc $masterrate \* $uspound) 62 | echo " British Pound: $rate" 63 | 64 | exit 0 65 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/066-getexchrate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # getexchrate - scrape the current currency exchange rates 4 | # from CNN's money and finance Web site. 5 | # 6 | # Without any flags, this grabs the exchange rate values if the 7 | # current information is more than 12 hours old. It also shows 8 | # success upon completion: something to take into account if 9 | # you run this from a cron job. 10 | 11 | url="http://money.cnn.com/markets/currencies/crosscurr.html" 12 | age="+720" # 12 hours, in minutes 13 | outf="/tmp/.exchangerate" 14 | 15 | # Do we need the new exchange rate values? Let's check to see: 16 | # if the file is less than 12 hours old, the find fails ... 17 | 18 | if [ -f $outf ] ; then 19 | if [ -z "$(find $outf -cmin $age -print)" ]; then 20 | echo "$0: exchange rate data is up-to-date." >&2 21 | exit 1 22 | fi 23 | fi 24 | 25 | # Actually get the latest exchange rates, translating into the 26 | # format required by the exchrate script. 27 | 28 | lynx -dump 'http://money.cnn.com/markets/currencies/crosscurr.html' | \ 29 | grep -E '(Japan|Euro|Can|UK)' | \ 30 | awk '{ if (NF == 5 ) { print $1"="$2} }' | \ 31 | tr '[:upper:]' '[:lower:]' | \ 32 | sed 's/dollar/cand/' > $outf 33 | 34 | echo "Success. Exchange rates updated at $(date)." 35 | 36 | exit 0 37 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/067-getstock.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # getstock - given a stock ticker symbol, return its current value 4 | # from the Lycos web site 5 | 6 | url="http://finance.lycos.com/qc/stocks/quotes.aspx?symbols=" 7 | 8 | if [ $# -ne 1 ] ; then 9 | echo "Usage: $(basename $0) stocksymbol" >&2 10 | exit 1 11 | fi 12 | 13 | value="$(lynx -dump "$url$1" | grep 'Last price:' | \ 14 | awk -F: 'NF > 1 && $(NF) != "N/A" { print $(NF) }')" 15 | 16 | if [ -z $value ] ; then 17 | echo "error: no value found for ticker symbol $1." >&2 18 | exit 1 19 | fi 20 | 21 | echo $value 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/067-portfolio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # portfolio - calculate the value of each stock in your holdings, 4 | # then calculate the value of your overall portfolio, based on 5 | # the latest stock market position. 6 | 7 | getstock="sh 069-getstock.sh" 8 | scriptbc="$HOME/bin/scriptbc" 9 | portfolio="$HOME/.portfolio" 10 | 11 | if [ ! -f $portfolio ] ; then 12 | echo "$(basename $0): No portfolio to check? ($portfolio)" >&2 13 | exit 1 14 | fi 15 | 16 | while read holding 17 | do 18 | eval $(echo $holding | \ 19 | awk -F\| '{print "name=\""$1"\"; ticker=\""$2"\"; hold=\""$3"\""}') 20 | if [ ! -z "$ticker" ] ; then 21 | value="$(eval $getstock $ticker)" 22 | totval="$($scriptbc ${value:-0} \* $hold)" 23 | echo "$name is trading at $value (your $hold shares = $totval)" 24 | sumvalue="$($scriptbc ${sumvalue:-0} + $totval)" 25 | fi 26 | done < $portfolio 27 | 28 | echo "Total portfolio value: $sumvalue" 29 | 30 | exit 0 31 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/069-showcgienv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # show CGI env - display the CGI runtime environment, as given to any 4 | # CGI script on this system. 5 | 6 | echo "Content-type: text/html" 7 | echo "" 8 | 9 | # now the real information 10 | 11 | echo "<html><body bgcolor=\"white\"><h2>CGI Runtime Environment</h2>" 12 | echo "<pre>" 13 | env || printenv 14 | echo "</pre>" 15 | echo "<h3>Input stream is:</h3>" 16 | echo "<pre>" 17 | cat - 18 | echo "(end of input stream)</pre></body></html>" 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/070-logsearch.cgi: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # log Yahoo! search - given a search request, log the pattern, then 4 | # feed the entire sequence to the real Yahoo search system. 5 | 6 | logfile="/home/taylor/scripts/searchlog.txt" 7 | 8 | if [ ! -f $logfile ] ; then 9 | touch $logfile 10 | chmod a+rw $logfile 11 | fi 12 | 13 | if [ -w $logfile ] ; then 14 | echo "$(date): $QUERY_STRING" | sed 's/p=//g;s/+/ /g' >> $logfile 15 | fi 16 | 17 | # echo "Content-type: text/html" 18 | # echo "" 19 | 20 | echo "Location: http://search.yahoo.com/bin/search?$QUERY_STRING" 21 | echo "" 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/070-yahoo-search.html: -------------------------------------------------------------------------------- 1 | <form method="get" action="072-logsearch.cgi"> 2 | Search Yahoo: 3 | <input type="text" name="p"> 4 | <input type="submit" value="search"> 5 | </form> 6 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/071-getdope.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Within cron set it up so that every Friday, grab the latest column 4 | # of 'The Straight Dope' and mail it out to the specified recipient 5 | 6 | now="$(date +%y%m%d)" 7 | url="http://www.straightdope.com/columns/${now}.html" 8 | to="taylor" 9 | 10 | ( cat << EOF 11 | Subject: The Straight Dope for $(date "+%A, %d %B, %Y") 12 | From: Cecil Adams <www@intuitive.com> 13 | Content-type: text/html 14 | To: $to 15 | 16 | <html> 17 | <body border=0 leftmargin=0 topmargin=0> 18 | <div style='background-color:309;color:fC6;font-size:45pt; 19 | font-style:sans-serif;font-weight:900;text-align:center; 20 | margin:0;padding:3px;'> 21 | THE STRAIGHT DOPE</div> 22 | 23 | <div style='padding:3px;line-height:1.1'> 24 | EOF 25 | 26 | lynx -source "$url" | \ 27 | sed -n '/<hr>/,$p' | \ 28 | sed 's|src="../art|src="http://www.straightdope.com/art|' |\ 29 | sed 's|href="..|href="http://www.straightdope.com|g' 30 | 31 | echo "</div></body></html>" 32 | ) | /usr/sbin/sendmail -t 33 | 34 | exit 0 35 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/071-kevin-and-kell.cgi: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # kevin-and-kell.cgi - Build a Web page on-the-fly to display the latest 4 | # strip from the cartoon strip Kevin and Kell, by Bill Holbrook 5 | # <Strip referenced with permission of the cartoonist> 6 | 7 | month="$(date +%m)" 8 | day="$(date +%d)" 9 | year="$(date +%y)" 10 | 11 | echo "Content-type: text/html" 12 | echo "" 13 | 14 | echo "<html><body bgcolor=white><center>" 15 | echo "<title>Kevin & Kell" 16 | echo "" 17 | echo "" 18 | echo "" 19 | echo "
    Bill Holbrook's Kevin & Kell
    " 25 | 26 | echo "
    " 27 | echo "© Bill Holbrook. Please see " 28 | echo "kevinandkell.com" 29 | echo "for more strips, books, etc." 30 | echo "
    " 31 | 32 | exit 0 33 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/072-contactus.cgi: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Process the contact us form data, email it to the designated 4 | # recipient, and return a succinct thank you message. 5 | 6 | recipient="taylor" 7 | thankyou="thankyou.html" # optional 'thanks' page 8 | 9 | ( cat << EOF 10 | From: (Your Web Site Contact Form) www@$(hostname) 11 | To: $recipient 12 | Subject: Contact Request from Web Site 13 | 14 | Content of the Web site contact form: 15 | 16 | EOF 17 | 18 | cat - | tr '&' '\n' | \ 19 | sed -e 's/+/ /g' -e 's/%40/@/g' -e 's/=/: /' 20 | 21 | echo ""; echo "" 22 | echo "Form submitted on $(date)" 23 | ) | sendmail -t 24 | 25 | echo "Content-type: text/html" 26 | echo "" 27 | 28 | if [ -r $thankyou ] ; then 29 | cat $thankyou 30 | else 31 | echo "" 32 | echo "Thank you. We'll try to contact you soonest." 33 | echo "" 34 | fi 35 | 36 | exit 0 37 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/072-contactus.html: -------------------------------------------------------------------------------- 1 | 2 | contact us! 3 |
    4 |
    5 |
    We Love Feedback!
    6 | Name:
    7 | Email:
    8 | 9 | Your message or comment (please be brief):
    10 |
    11 | 12 |
    13 | And this is an example sentence with a werd or two misspelled, for the 14 | webspell script (script #84). 15 |
    16 | 17 | 18 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/073-photoalbum.cgi: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Content-type: text/html" 4 | echo "" 5 | 6 | header="header.html" 7 | footer="footer.html" 8 | count=0 9 | 10 | if [ -f $header ] ; then 11 | cat $header 12 | else 13 | echo "
    " 14 | fi 15 | 16 | echo "

    Contents of $(dirname $SCRIPT_NAME)

    " 17 | echo "" 18 | 19 | for name in *jpg 20 | do 21 | if [ $count -eq 4 ] ; then 22 | echo "
    " 23 | count=1 24 | else 25 | echo "" 26 | count=$(( $count + 1 )) 27 | fi 28 | 29 | nicename="$(echo $name | sed 's/.jpg//;s/-/ /g')" 30 | 31 | echo "
    " 33 | echo "$nicename" 34 | done 35 | 36 | echo "
    " 37 | 38 | if [ -f $footer ] ; then 39 | cat $footer 40 | else 41 | echo "" 42 | fi 43 | 44 | exit 0 45 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/074-guestbook.txt: -------------------------------------------------------------------------------- 1 | Sat Sep 6 14:57:02 MST 2003|Lucas Gonze|lucas@gonze.com|I very much enjoyed my stay at your web site. Best of luck. 2 | Sat Sep 6 22:54:49 MST 2003|Dee-Ann LeBlanc|dee@renaissoft.com|Kinda plain, but that's better than it being covered in animations and flaming text. :) 3 | Sun Sep 7 02:50:48 MST 2003|MC|null@mcslp.com|I don't want the world, I just want your half. 4 | Tue Sep 9 02:34:48 MST 2003|Andrey Bronfin|andreyb@elrontelesoft.com|Nice to be here. 5 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/075-counter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # counter - a simple text-based page counter, with appropriate locking 4 | 5 | myhome="/home/taylor/web/wicked/examples" 6 | counter="$myhome/counter.dat" 7 | lockfile="$myhome/counter.lck" 8 | updatecounter="$myhome/updatecounter" 9 | 10 | # Note that this script is not intended to be called directly from 11 | # a web browser so it doesn't use the otherwise obligatory 12 | # content-type header material. 13 | 14 | # ascertain whether we have lockf or lockfile system apps 15 | 16 | if [ -z $(which lockf) ] ; then 17 | if [ -z $(which lockfile) ] ; then 18 | echo "(counter: no locking utility available)
    " 19 | exit 0 20 | else # proceed with the lockfile command 21 | if [ ! -f $counter ] ; then 22 | echo "0" # it'll be created shortly 23 | else 24 | cat $counter 25 | fi 26 | 27 | trap "/bin/rm -f $lockfile" 0 28 | 29 | lockfile -1 -l 10 -s 2 $lockfile 30 | if [ $? -ne 0 ] ; then 31 | echo "(counter: couldn't create lockfile in time)" 32 | exit 0 33 | fi 34 | $updatecounter $counter 35 | fi 36 | else 37 | if [ ! -f $counter ] ; then 38 | echo "0" # it'll be created shortly 39 | else 40 | cat $counter 41 | fi 42 | 43 | lockf -s -t 10 $lockfile $updatecounter $counter 44 | if [ $? -ne 0 ] ; then 45 | echo "(counter: couldn't create lockfile in time)" 46 | fi 47 | fi 48 | 49 | exit 0 50 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/075-page-with-counter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

    Sample Web Page with Counter Substitution

    4 | This page has been visited ---countervalue--- times, 5 | and you must therefore be visitor 6 | ---countervalue--- 7 | out of 8 | ---countervalue--- 9 | visitors! 10 | 11 | 12 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/075-streamfile.cgi: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # streamfile - output an HTML file, replacing the sequence 4 | # ---countervalue--- with the current counter value. 5 | 6 | infile="page-with-counter.html" 7 | counter="./counter.cgi" 8 | 9 | echo "Content-type: text/html" 10 | echo "" 11 | 12 | value="$(counter)" 13 | 14 | sed "s/---countervalue---/$value/g" < $infile 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/075-updatecounter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # updatecounter - a tiny script that updates the counter file to 4 | # the value specified. Assumes that locking is done elsewhere. 5 | 6 | if [ $# -ne 1 ] ; then 7 | echo "Usage: $0 countfile"; exit 1 8 | fi 9 | 10 | count="$(cat $1)" 11 | newcount="$(( ${count:-0} + 1 ))" 12 | 13 | echo "$newcount" > $1 14 | chmod a+rw $1 15 | 16 | exit 0 17 | 18 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/076-ssi-sample.html: -------------------------------------------------------------------------------- 1 | 2 | Server side include demonstration 3 | 4 |

    Server-side include demonstration page

    5 | You are visitor 6 | 8 | to this site. 9 |

    10 | This page was last modified on 11 | 12 | according to the SSI LAST_MODIFIED variable. 13 |

    14 | Finally, the random tagline for this load is: 15 |

    16 | 19 |
    20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/077-checklinks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # checklinks - traverse all internal URLs on a Web site, reporting 4 | # any errors in the "traverse.errors" file. 5 | 6 | lynx="/usr/local/bin/lynx" # this might need to be tweaked 7 | 8 | # remove all the lynx traversal output files upon completion: 9 | trap "/bin/rm -f traverse*.errors reject*.dat traverse*.dat" 0 10 | 11 | if [ -z "$1" ] ; then 12 | echo "Usage: checklinks URL" >&2 ; exit 1 13 | fi 14 | 15 | $lynx -traversal "$1" > /dev/null 16 | 17 | if [ -s "traverse.errors" ] ; then 18 | echo -n $(wc -l < traverse.errors) errors encountered. 19 | echo \ Checked $(grep '^http' traverse.dat | wc -l) pages at ${1}: 20 | sed "s|$1||g" < traverse.errors 21 | else 22 | echo -n "No errors encountered. "; 23 | echo Checked $(grep '^http' traverse.dat | wc -l) pages at ${1} 24 | exit 0 25 | fi 26 | 27 | baseurl="$(echo $1 | cut -d/ -f3)" 28 | mv traverse.errors ${baseurl}.errors 29 | echo "(A copy of this output has been saved in ${baseurl}.errors)" 30 | 31 | exit 0 32 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/078-checkexternal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # checkexternal - traverse all internal URLs on a Web site to build a 4 | # list of external references, then check each one to ascertain 5 | # which might be dead or otherwise broken. The -a flag forces the 6 | # script to list all matches, whether they're accessible or not: by 7 | # default only unreachable links are shown. 8 | 9 | lynx="/usr/local/bin/lynx" # might need to be tweaked 10 | listall=0; errors=0 # shortcut: two vars on one line! 11 | 12 | if [ "$1" = "-a" ] ; then 13 | listall=1; shift 14 | fi 15 | 16 | outfile="$(echo "$1" | cut -d/ -f3).external-errors" 17 | 18 | /bin/rm -f $outfile # clean it for new output 19 | 20 | trap "/bin/rm -f traverse*.errors reject*.dat traverse*.dat" 0 21 | 22 | if [ -z "$1" ] ; then 23 | echo "Usage: $(basename $0) [-a] URL" >&2 24 | exit 1 25 | fi 26 | 27 | # create the data files needed 28 | $lynx -traversal $1 > /dev/null; 29 | 30 | if [ -s "reject.dat" ] ; then 31 | # The following line has a trailing space after the backslash! 32 | echo -n $(sort -u reject.dat | wc -l) external links encountered 33 | echo \ in $(grep '^http' traverse.dat | wc -l) pages 34 | 35 | for URL in $(grep '^http:' reject.dat | sort -u) 36 | do 37 | if ! $lynx -dump $URL > /dev/null 2>&1 ; then 38 | echo "Failed : $URL" >> $outfile 39 | errors="$(( $errors + 1 ))" 40 | elif [ $listall -eq 1 ] ; then 41 | echo "Success: $URL" >> $outfile 42 | fi 43 | done 44 | 45 | if [ -s $outfile ] ; then 46 | cat $outfile 47 | echo "(A copy of this output has been saved in ${outfile})" 48 | elif [ $listall -eq 0 -a $errors -eq 0 ] ; then 49 | echo "No problems encountered." 50 | fi 51 | else 52 | echo -n "No external links encountered " 53 | echo in $(grep '^http' traverse.dat | wc -l) pages. 54 | fi 55 | 56 | exit 0 57 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/079-webspell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # webspell - use the 'aspell' feature + lynx to spell check either a 4 | # Web page URL or a file. 5 | 6 | # Inevitably you'll find that there are words it flags as wrong, but 7 | # you think are fine. Simply save them in a file, one-per-line, and 8 | # ensure that 'okaywords' points to that file. 9 | 10 | okaywords="$HOME/.okaywords" 11 | tempout="/tmp/webspell.$$" 12 | trap "/bin/rm -f $tempout" 0 13 | 14 | if [ $# -eq 0 ] ; then 15 | echo "Usage: webspell file|URL" >&2; exit 1 16 | fi 17 | 18 | for filename 19 | do 20 | if [ ! -f "$filename" -a "$(echo $filename|cut -c1-7)" != "http://" ] ; then 21 | continue; # picked up directory in '*' listing 22 | fi 23 | 24 | lynx -dump $filename | tr ' ' '\n' | sort -u | \ 25 | grep -vE "(^[^a-z]|')" | \ 26 | # adjust the following line to produce just a list of misspelled words 27 | ispell -a | awk '/^\&/ { print $2 }' | \ 28 | sort -u > $tempout 29 | 30 | if [ -r $okaywords ] ; then 31 | # if you have an okaywords file, screen okay words out 32 | grep -vif $okaywords < $tempout > ${tempout}.2 33 | mv ${tempout}.2 $tempout 34 | fi 35 | 36 | if [ -s $tempout ] ; then 37 | echo "Probable spelling errors: ${filename}" 38 | echo '-------' ; cat $tempout ; echo '=========' 39 | cat $tempout | paste - - - - | sed 's/^/ /' 40 | fi 41 | done 42 | 43 | exit 0 44 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/080-apm-footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 |
    5 | 6 | 35 |
    Password Manager Actions
    7 |
    8 | 9 | 15 |
    10 | add user: 11 |
    12 | password: 13 | 14 |
    16 |
    17 |
    18 | 19 | 25 |
    20 | update 21 |
    22 | password: 23 | 24 |
    26 |
    27 |
    delete 29 |
    30 |
    31 |
    33 |
    34 |
    36 | 37 | 38 |
    From the book 39 | Wicked Cool Shell Scripts
    40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/080-htpasswd-b.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | if (! scalar @ARGV ) { 4 | print "Usage: htpasswd-b passwordfile user password\n"; 5 | print "(this program automatically creates the pw file if needed.)\n"; 6 | exit 0; 7 | } 8 | 9 | @saltsource = ('a'..'z', 'A'..'Z', '0'..'9','.','/'); 10 | $randum_num = int(rand(scalar @saltsource)); 11 | $salt = $saltsource[$randum_num]; 12 | $randum_num = int(rand(scalar @saltsource)); 13 | $salt .= $saltsource[$randum_num]; 14 | 15 | $outf=$ARGV[0]; 16 | $user=$ARGV[1]; 17 | $passwd=$ARGV[2]; 18 | 19 | if ($user && $passwd) { 20 | $encrypted = crypt($passwd, "$salt"); 21 | 22 | if (-f $outf) { 23 | open(OUT, ">>$outf") || die "htpasswd-b error: $!\n"; 24 | } else { 25 | open(OUT, ">$outf") || die "htpasswd-b error: $!\n"; 26 | } 27 | print OUT "$user:$encrypted\n"; 28 | close(OUT); 29 | 30 | exit 0; 31 | } 32 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/081-ftpsyncup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # ftpsyncup - Given a target directory on an ftp server, make sure that 4 | # all new or modified files are uploaded to the remote system. Uses 5 | # a timestamp file ingeniously called .timestamp to keep track. 6 | 7 | timestamp=".timestamp" 8 | tempfile="/tmp/ftpsyncup.$$" 9 | count=0 10 | 11 | trap "/bin/rm -f $tempfile" 0 1 15 # zap tempfile on exit &sigs 12 | 13 | if [ $# -eq 0 ] ; then 14 | echo "Usage: $0 user@host { remotedir }" >&2 15 | exit 1 16 | fi 17 | 18 | user="$(echo $1 | cut -d@ -f1)" 19 | server="$(echo $1 | cut -d@ -f2)" 20 | 21 | echo "open $server" > $tempfile 22 | echo "user $user" >> $tempfile 23 | 24 | if [ $# -gt 1 ] ; then 25 | echo "cd $2" >> $tempfile 26 | fi 27 | 28 | if [ ! -f $timestamp ] ; then 29 | # no timestamp file, upload all files 30 | for filename in * 31 | do 32 | if [ -f "$filename" ] ; then 33 | echo "put \"$filename\"" >> $tempfile 34 | count=$(( $count + 1 )) 35 | fi 36 | done 37 | else 38 | for filename in $(find . -newer $timestamp -type f -print) 39 | do 40 | echo "put \"$filename\"" >> $tempfile 41 | count=$(( $count + 1 )) 42 | done 43 | fi 44 | 45 | if [ $count -eq 0 ] ; then 46 | echo "$0: No files require uploading to $server" >&2 47 | exit 0 48 | fi 49 | 50 | echo "quit" >> $tempfile 51 | 52 | echo "Synchronizing: Found $count files in local folder to upload." 53 | 54 | if ! ftp -n < $tempfile ; then 55 | echo "Done. All files synchronized up with $server" 56 | touch $timestamp 57 | fi 58 | 59 | exit 0 60 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/082-ftpsyncdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # ftpsyncdown - Given a source directory on a remote FTP server, 4 | # download all the files therein into the current directory. 5 | 6 | tempfile="/tmp/ftpsyncdown.$$" 7 | 8 | trap "/bin/rm -f $tempfile" 0 1 15 # zap tempfile on exit 9 | 10 | if [ $# -eq 0 ] ; then 11 | echo "Usage: $0 user@host { remotedir }" >&2 12 | exit 1 13 | fi 14 | 15 | user="$(echo $1 | cut -d@ -f1)" 16 | server="$(echo $1 | cut -d@ -f2)" 17 | 18 | echo "open $server" > $tempfile 19 | echo "user $user" >> $tempfile 20 | 21 | if [ $# -gt 1 ] ; then 22 | echo "cd $2" >> $tempfile 23 | fi 24 | 25 | cat << EOF >> $tempfile 26 | prompt 27 | mget * 28 | quit 29 | EOF 30 | 31 | echo "Synchronizing: Downloading files" 32 | 33 | if ! ftp -n < $tempfile ; then 34 | echo "Done. All files on $server downloaded to $(pwd)" 35 | fi 36 | 37 | exit 0 38 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/083-sftpsync.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # sftpsync - Given a target directory on an sftp server, make sure that 4 | # all new or modified files are uploaded to the remote system. Uses 5 | # a timestamp file ingeniously called .timestamp to keep track. 6 | 7 | timestamp=".timestamp" 8 | tempfile="/tmp/sftpsync.$$" 9 | count=0 10 | 11 | trap "/bin/rm -f $tempfile" 0 1 15 # zap tempfile on exit &sigs 12 | 13 | if [ $# -eq 0 ] ; then 14 | echo "Usage: $0 user@host { remotedir }" >&2 15 | exit 1 16 | fi 17 | 18 | user="$(echo $1 | cut -d@ -f1)" 19 | server="$(echo $1 | cut -d@ -f2)" 20 | 21 | if [ $# -gt 1 ] ; then 22 | echo "cd $2" >> $tempfile 23 | fi 24 | 25 | if [ ! -f $timestamp ] ; then 26 | # no timestamp file, upload all files 27 | for filename in * 28 | do 29 | if [ -f "$filename" ] ; then 30 | echo "put -P \"$filename\"" >> $tempfile 31 | count=$(( $count + 1 )) 32 | fi 33 | done 34 | else 35 | for filename in $(find . -newer $timestamp -type f -print) 36 | do 37 | echo "put -P \"$filename\"" >> $tempfile 38 | count=$(( $count + 1 )) 39 | done 40 | fi 41 | 42 | if [ $count -eq 0 ] ; then 43 | echo "$0: No files require uploading to $server" >&2 44 | exit 1 45 | fi 46 | 47 | echo "quit" >> $tempfile 48 | 49 | echo "Synchronizing: Found $count files in local folder to upload." 50 | 51 | if ! sftp -b $tempfile "$user@$server" ; then 52 | echo "Done. All files synchronized up with $server" 53 | touch $timestamp 54 | fi 55 | 56 | exit 0 57 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/083-ssync.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # ssync - If anything's changed, Create a tarball and sync a remote 4 | # directory via sftp using sftpsync. 5 | 6 | sftpacct="taylor@intuitive.com" 7 | tarballname="AllFiles.tgz" 8 | localsource="$HOME/scripts" 9 | remotedir="shellhacks/scripts" 10 | timestamp=".timestamp" 11 | 12 | sftpsync="$HOME/scripts/sftpsync" 13 | 14 | # first off, let's see if the local dir exists and has files. 15 | 16 | if [ ! -d $localsource ] ; then 17 | echo "$0: Error: directory $localsource doesn't exist?" >&2 18 | exit 1 19 | fi 20 | 21 | cd $localsource 22 | 23 | # now let's count files to ensure something's changed: 24 | 25 | if [ ! -f $timestamp ] ; then 26 | for filename in * 27 | do 28 | if [ -f "$filename" ] ; then 29 | count=$(( $count + 1 )) 30 | fi 31 | done 32 | else 33 | count=$(find . -newer $timestamp -type f -print | wc -l) 34 | fi 35 | 36 | if [ ${count:-0} -eq 0 ] ; then 37 | echo "$0: No files found in $localsource to sync with remote." >&2 38 | exit 0 39 | fi 40 | 41 | echo "Making tarball archive file for upload" 42 | 43 | tar -czf $tarballname ./* 44 | 45 | # Done! Now let's switch to the sftpsync script 46 | 47 | exec $sftpsync $sftpacct $remotedir 48 | 49 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/084-webaccess.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # webaccess - analyze an Apache-format access_log file, extracting 4 | # useful and interesting statistics 5 | 6 | bytes_in_gb=1048576 7 | scriptbc="$HOME/bin/scriptbc" 8 | nicenumber="$HOME/bin/nicenumber" 9 | host="intuitive.com" 10 | 11 | if [ $# -eq 0 -o ! -f "$1" ] ; then 12 | echo "Usage: $(basename $0) logfile" >&2 13 | exit 1 14 | fi 15 | 16 | firstdate="$(head -1 "$1" | awk '{print $4}' | sed 's/\[//')" 17 | lastdate="$(tail -1 "$1" | awk '{print $4}' | sed 's/\[//')" 18 | 19 | echo "Results of analyzing log file $1" 20 | echo "" 21 | echo " Start date: $(echo $firstdate|sed 's/:/ at /')" 22 | echo " End date: $(echo $lastdate|sed 's/:/ at /')" 23 | 24 | hits="$(wc -l < "$1" | sed 's/[^[:digit:]]//g')" 25 | 26 | echo " Hits: $($nicenumber $hits) (total accesses)" 27 | 28 | pages="$(grep -ivE '(.txt|.gif|.jpg|.png)' "$1" | wc -l | sed 's/[^[:digit:]]//g')" 29 | 30 | echo " Pageviews: $($nicenumber $pages) (hits minus graphics)" 31 | 32 | totalbytes="$(awk '{sum+=$10} END {print sum}' "$1")" 33 | 34 | echo -n " Transferred: $($nicenumber $totalbytes) bytes " 35 | 36 | if [ $totalbytes -gt $bytes_in_gb ] ; then 37 | echo "($($scriptbc $totalbytes / $bytes_in_gb) GB)" 38 | elif [ $totalbytes -gt 1024 ] ; then 39 | echo "($($scriptbc $totalbytes / 1024) MB)" 40 | else 41 | echo "" 42 | fi 43 | 44 | # now let's scrape the log file for some useful data: 45 | 46 | echo "" 47 | echo "The ten most popular pages were:" 48 | 49 | awk '{print $7}' "$1" | grep -ivE '(.gif|.jpg|.png)' | \ 50 | sed 's/\/$//g' | sort | \ 51 | uniq -c | sort -rn | head -10 52 | 53 | echo "" 54 | 55 | echo "The ten most common referrer URLs were:" 56 | 57 | awk '{print $11}' "$1" | \ 58 | grep -vE "(^"-"$|/www.$host|/$host)" | \ 59 | sort | uniq -c | sort -rn | head -10 60 | 61 | echo "" 62 | exit 0 63 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/085-enginehits.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # enginehits - extract and analyze search engine traffic in the 4 | # referrer field of a Common Log Format access log for a 5 | # specified domain name. 6 | 7 | maxmatches=25 8 | count=0 9 | temp="/tmp/$(basename $0).$$" 10 | 11 | trap "/bin/rm -f $temp" 0 12 | 13 | if [ $# -eq 0 -o ! -f "$1" ] ; then 14 | echo "Usage: $(basename $0) logfile searchdomain" >&2 15 | exit 1 16 | fi 17 | 18 | for URL in $(awk '{ if (length($11) > 4) { print $11 } }' "$1" | \ 19 | grep $2) 20 | do 21 | args="$(echo $URL | cut -d\? -f2 | tr '&' '\n' | \ 22 | grep -E '(^q=|^sid=|^p=|query=|item=|ask=|name=|topic=)' | \ 23 | cut -d= -f2)" 24 | echo $args | sed -e 's/+/ /g' -e 's/"//g' >> $temp 25 | count="$(( $count + 1 ))" 26 | done 27 | 28 | echo "Search engine referrer info extracted $2 searches from ${1}:" 29 | 30 | sort $temp | uniq -c | sort -rn | head -$maxmatches | sed 's/^/ /g' 31 | 32 | echo "" 33 | echo Scanned $count $2 entries in log file out of $(wc -l < "$1") total. 34 | 35 | exit 0 36 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/085-searchinfo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # searchinfo - extract and analyze search engine traffic indicated in the 4 | # referrer field of a Common Log Format access log. 5 | 6 | host="intuitive.com" # change to your domain, as desired 7 | maxmatches=20 8 | count=0 9 | temp="/tmp/$(basename $0).$$" 10 | 11 | trap "/bin/rm -f $temp" 0 12 | 13 | if [ $# -eq 0 ] ; then 14 | echo "Usage: $(basename $0) logfile" >&2 15 | exit 1 16 | fi 17 | if [ ! -r "$1" ] ; then 18 | echo "Error: can't open file $1 for analysis." >&2 19 | exit 1 20 | fi 21 | 22 | for URL in $(awk '{ if (length($11) > 4) { print $11 } }' "$1" | \ 23 | grep -vE "(/www.$host|/$host)" | grep '?') 24 | do 25 | searchengine="$(echo $URL | cut -d/ -f3 | rev | cut -d. -f1-2 | rev)" 26 | args="$(echo $URL | cut -d\? -f2 | tr '&' '\n' | \ 27 | grep -E '(^q=|^sid=|^p=|query=|item=|ask=|name=|topic=)' | \ 28 | sed -e 's/+/ /g' -e 's/%20/ /g' -e 's/"//g' | cut -d= -f2)" 29 | 30 | if [ ! -z "$args" ] ; then 31 | echo "${searchengine}: $args" >> $temp 32 | else 33 | # no well-known match, show entire GET string instead... 34 | echo "${searchengine} $(echo $URL | cut -d\? -f2)" >> $temp 35 | fi 36 | count="$(( $count + 1 ))" 37 | done 38 | 39 | echo "Search engine referrer info extracted from ${1}:" 40 | 41 | sort $temp | uniq -c | sort -rn | head -$maxmatches | sed 's/^/ /g' 42 | 43 | echo "" 44 | echo Scanned $count entries in log file out of $(wc -l < "$1") total. 45 | 46 | exit 0 47 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/087-remotebackup-filelist: -------------------------------------------------------------------------------- 1 | *.sh 2 | *.html 3 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/087-remotebackup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # remotebackup - This script takes a list of files and directories, 4 | # builds a single archive, compressed, then emails it off to a 5 | # remote archive site for safekeeping. It's intended to be run 6 | # every night for critical user files, but not intended to 7 | # replace a more rigorous backup scheme. You should strongly 8 | # consider using 'unpacker' on the remote end too. 9 | 10 | uuencode="/usr/bin/uuencode" 11 | outfile="/tmp/rb.$$.tgz" 12 | outfname="backup.$(date +%y%m%d).tgz" 13 | infile="/tmp/rb.$$.in" 14 | 15 | trap "/bin/rm -f $outfile $infile" 0 16 | 17 | if [ $# -ne 2 -a $# -ne 3 ] ; then 18 | echo "Usage: $(basename $0) backup-file-list remoteaddr {targetdir}" >&2 19 | exit 1 20 | fi 21 | 22 | if [ ! -s "$1" ] ; then 23 | echo "Error: backup list $1 is empty or missing" >&2 24 | exit 1 25 | fi 26 | 27 | # Scan entries and build fixed infile list. This expands wildcards 28 | # and escapes spaces in filenames with a backslash, producing a 29 | # change: "this file" becomes this\ file so quotes are not needed. 30 | 31 | while read entry; do 32 | echo "$entry" | sed -e 's/ /\\ /g' >> $infile 33 | done < "$1" 34 | 35 | # The actual work of building the archive, encoding it, and sending it 36 | 37 | tar czf - $(cat $infile) | \ 38 | $uuencode $outfname | \ 39 | mail -s "${3:-Backup archive for $(date)}" "$2" 40 | 41 | echo "Done. $(basename $0) backed up the following files:" 42 | sed 's/^/ /' $infile 43 | echo -n "and mailed them to $2 " 44 | if [ ! -z "$3" ] ; then 45 | echo "with requested target directory $3" 46 | else 47 | echo "" 48 | fi 49 | 50 | exit 0 51 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/087-trimmailbox.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # trimmailbox - a simple script to ensure that only the four most recent 4 | # messages remain in the users mailbox. Works with Berkeley Mail 5 | # (aka Mailx or mail): will need modifications for other mailers!! 6 | 7 | keep=4 # by default, let's just keep around the four most recent messages 8 | 9 | totalmsgs="$(echo 'x' | mail | sed -n '2p' | awk '{print $2}')" 10 | 11 | if [ $totalmsgs -lt $keep ] ; then 12 | exit 0 # nothing to do 13 | fi 14 | 15 | topmsg="$(( $totalmsgs - $keep ))" 16 | 17 | mail > /dev/null << EOF 18 | d1-$topmsg 19 | q 20 | EOF 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/090-getstats.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # getstats - every 'n' minutes, grab netstats values (via crontab) 4 | 5 | logfile="/var/log/netstat.log" 6 | temp="/tmp/getstats.tmp" 7 | 8 | trap "/bin/rm -f $temp" 0 9 | 10 | ( echo -n "time=$(date +%s);" 11 | 12 | netstat -s -p tcp > $temp 13 | 14 | sent="$(grep 'packets sent' $temp | cut -d\ -f1 | sed 's/[^[:digit:]]//g')" 15 | resent="$(grep 'retransmitted' $temp | cut -d\ -f1 | sed 's/[^[:digit:]]//g')" 16 | received="$(grep 'packets received$' $temp | cut -d\ -f1 | sed 's/[^[:digit:]]//g')" 17 | dupacks="$(grep 'duplicate acks' $temp | cut -d\ -f1 | sed 's/[^[:digit:]]//g')" 18 | outoforder="$(grep 'out-of-order packets' $temp | cut -d\ -f1 | sed 's/[^[:digit:]]//g')" 19 | connectreq="$(grep 'connection requests' $temp | cut -d\ -f1 | sed 's/[^[:digit:]]//g')" 20 | connectacc="$(grep 'connection accepts' $temp | cut -d\ -f1 | sed 's/[^[:digit:]]//g')" 21 | retmout="$(grep 'retransmit timeouts' $temp | cut -d\ -f1 | sed 's/[^[:digit:]]//g')" 22 | 23 | echo -n "snt=$sent;re=$resent;rec=$received;dup=$dupacks;" 24 | echo -n "oo=$outoforder;creq=$connectreq;cacc=$connectacc;" 25 | echo "reto=$retmout" 26 | 27 | ) >> $logfile 28 | 29 | exit 0 30 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/091-watch-and-nice.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # watch and nice - watch for the specified process name, and renice 4 | # to the desired value when seen 5 | 6 | renicename="$HOME/bin/renicename" 7 | 8 | if [ $# -ne 2 ] ; then 9 | echo "Usage: $(basename $0) desirednice jobname" >&2 10 | exit 1 11 | fi 12 | 13 | pid="$($renicename -p "$2")" 14 | 15 | if [ ! -z "$(echo $pid | sed 's/[0-9]*//g')" ] ; then 16 | echo "Failed to make a unique match in the process table for $2" >&2 17 | exit 1 18 | fi 19 | 20 | currentnice="$(ps -lp $pid | tail -1 | awk '{print $6}')" 21 | 22 | if [ $1 -gt $currentnice ] ; then 23 | echo "Adjusting priority of $2 to $1" 24 | renice $1 $pid 25 | fi 26 | 27 | exit 0 28 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/093-listmacusers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Simple script to list users in the Mac OS X NetInfo database 4 | # note that Mac OS X also has an /etc/passwd file, but that's 5 | # only used during the initial stages of boot time and for 6 | # recovery bootups. Otherwise, all data is in the NetInfo db. 7 | 8 | fields="" 9 | 10 | while getopts "Aahnprsu" opt ; do 11 | case $opt in 12 | A ) fields="uid passwd name realname home shell" ;; 13 | a ) fields="uid name realname home shell" ;; 14 | h ) fields="$fields home" ;; 15 | n ) fields="$fields name" ;; 16 | p ) fields="$fields passwd" ;; 17 | r ) fields="$fields realname" ;; 18 | s ) fields="$fields shell" ;; 19 | u ) fields="$fields uid" ;; 20 | ? ) cat << EOF >&2 21 | Usage: $0 [A|a|hnprsu] 22 | Where: 23 | -A output all known NetInfo user fields 24 | -a output only the interesting user fields 25 | -h show home directories of accounts 26 | -n show account names 27 | -p passwd (encrypted) 28 | -r show realname/fullname values 29 | -s show login shell 30 | -u uid 31 | EOF 32 | exit 1 33 | esac 34 | done 35 | 36 | exec nireport . /users ${fields:=uid name realname home shell} 37 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/095-addmacalias.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # addalias - add a new alias to the email alias database on Mac OS X 4 | # this presumes that you've enabled sendmail, which can be kind of 5 | # tricky. Go to http://www.macdevcenter.com/ and search for 'sendmail' 6 | # for some good reference works. 7 | 8 | showaliases="nidump aliases ." 9 | 10 | if [ "$(/usr/bin/whoami)" != "root" ] ; then 11 | echo "$(basename $0): You must be root to run this command." >&2 12 | exit 1 13 | fi 14 | 15 | if [ $# -eq 0 ] ; then 16 | echo -n "Alias to create: " 17 | read alias 18 | else 19 | alias=$1 20 | fi 21 | 22 | # now let's check to see if that alias already exists... 23 | 24 | if $showaliases | grep "${alias}:" >/dev/null 2>&1 ; then 25 | echo "$0: mail alias $alias already exists" >&2 26 | exit 1 27 | fi 28 | 29 | # looks good. let's get the RHS and inject it into NetInfo 30 | 31 | echo -n "pointing to: " 32 | read rhs 33 | 34 | niutil -create . /aliases/$alias 35 | niutil -createprop . /aliases/$alias name $alias 36 | niutil -createprop . /aliases/$alias members "$rhs" 37 | 38 | echo "Alias $alias created without incident." 39 | 40 | exit 0 41 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/096-titleterm.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # titleterm - tell the Mac OS X Terminal application to change its name 4 | # to the value specified as an argument to this succinct script. 5 | 6 | # To use this to show your current working directory, for example: 7 | # alias precmd 'titleterm "$PWD"' [tcsh] 8 | # or 9 | # export PROMPT_COMMAND="titleterm \"\$PWD\"" [bash] 10 | 11 | if [ $# -eq 0 ]; then 12 | echo "Usage: $0 title" >&2 13 | exit 1 14 | else 15 | echo -ne "\033]0;$1\007" 16 | fi 17 | 18 | exit 0 19 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/097-itunelist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # itunelist - list your iTunes library in a succinct and attractive 4 | # manner, suitable for sharing with others and using (with diff) 5 | # to ensure that you have synchronized iTune libraries on different 6 | # computers and laptops. 7 | 8 | itunehome="$HOME/Music/iTunes" 9 | ituneconfig="$itunehome/iTunes Music Library.xml" 10 | 11 | musiclib="/$(grep '>Music Folder<' "$ituneconfig" | cut -d/ -f5- | \ 12 | cut -d\< -f1 | sed 's/%20/ /g')" 13 | 14 | echo Your music library is at $musiclib 15 | 16 | if [ ! -d "$musiclib" ] ; then 17 | echo "$0: Confused: Music library $musiclib isn't a directory?" >&2 18 | exit 1 19 | fi 20 | 21 | exec find "$musiclib" -type d -mindepth 2 -maxdepth 2 \! -name '.*' -print | sed "s|$musiclib/||" 22 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/098-open2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # open2 - a smart wrapper for the cool Mac OS X 'open' command 4 | # to make it even more useful. By default, open launches the 5 | # appropriate application for a specified file or directory 6 | # based on the Aqua bindings, and has a limited ability to 7 | # launch applications if they're in the /Applications dir. 8 | 9 | # first off, whatever argument we're given, try it directly: 10 | 11 | open=/usr/bin/open 12 | 13 | if ! $open "$@" >/dev/null 2>&1 ; then 14 | if ! $open -a "$@" >/dev/null 2>&1 ; then 15 | 16 | # More than one arg? Don't know how to deal with it: quit 17 | if [ $# -gt 1 ] ; then 18 | echo "open: Can't figure out how to open or launch $@" >&2 19 | exit 1 20 | else 21 | case $(echo $1 | tr '[:upper:]' '[:lower:]') in 22 | acrobat ) app="Acrobat Reader" ;; 23 | adress* ) app="Address Book" ;; 24 | chat ) app="iChat" ;; 25 | cpu ) app="CPU Monitor" ;; 26 | dvd ) app="DVD Player" ;; 27 | excel ) app="Microsoft Excel" ;; 28 | netinfo ) app="NetInfo Manager" ;; 29 | prefs ) app="System Preferences" ;; 30 | print ) app="Print Center" ;; 31 | profil* ) app="Apple System Profiler" ;; 32 | qt|quicktime ) app="QuickTime Player" ;; 33 | sync ) app="iSync" ;; 34 | word ) app="Microsoft Word" ;; 35 | * ) echo "open: Don't know what to do with $1" >&2 36 | exit 1 37 | esac 38 | echo "You asked for $1 but I think you mean $app." >&2 39 | $open -a "$app" 40 | fi 41 | fi 42 | fi 43 | 44 | exit 0 45 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/AllFiles.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanshin/bin/251da0aafdd46479e789ab2fe8762ac767ab1662/Wicked Cool Scripts/AllFiles.tgz -------------------------------------------------------------------------------- /Wicked Cool Scripts/alice.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanshin/bin/251da0aafdd46479e789ab2fe8762ac767ab1662/Wicked Cool Scripts/alice.txt.gz -------------------------------------------------------------------------------- /Wicked Cool Scripts/big-word-list.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanshin/bin/251da0aafdd46479e789ab2fe8762ac767ab1662/Wicked Cool Scripts/big-word-list.txt.gz -------------------------------------------------------------------------------- /Wicked Cool Scripts/how-many-commands.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # how many commands: a simple script to count how many executable commands 4 | # are in your current PATH. 5 | 6 | myPATH="$(echo $PATH | sed -e 's/ /~~/g' -e 's/:/ /g')" 7 | count=0 ; nonex=0 8 | 9 | for dirname in $myPATH ; do 10 | directory="$(echo $dirname | sed 's/~~/ /g')" 11 | if [ -d "$directory" ] ; then 12 | for command in $(ls "$directory") ; do 13 | if [ -x "$directory/$command" ] ; then 14 | count="$(( $count + 1 ))" 15 | else 16 | nonex="$(( $nonex + 1 ))" 17 | fi 18 | done 19 | fi 20 | done 21 | 22 | echo "$count commands, and $nonex entires that weren't marked executable" 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/long-words.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanshin/bin/251da0aafdd46479e789ab2fe8762ac767ab1662/Wicked Cool Scripts/long-words.txt.gz -------------------------------------------------------------------------------- /Wicked Cool Scripts/palindrome.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # specify palindrome possibility as args 4 | 5 | if [ $# -eq 0 ] ; then 6 | echo Usage: $0 possible palindrome >&2 7 | exit 1 8 | fi 9 | 10 | testit="$(echo $@ | sed 's/[^[:alpha:]]//g' | tr '[:upper:]' '[:lower:]')" 11 | backwards="$(echo $testit | rev)" 12 | 13 | if [ "$testit" = "$backwards" ] ; then 14 | echo "$@ is a palindrome" 15 | else 16 | echo "$@ is not a palindrome" 17 | fi 18 | 19 | exit 0 20 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/ragged.txt: -------------------------------------------------------------------------------- 1 | So she sat on, with closed eyes, and half believed herself in 2 | Wonderland, though she knew she had but to open them again, and 3 | all would change to dull reality--the grass would be only rustling 4 | in the wind, and the pool rippling to the waving of the reeds--the 5 | rattling teacups would change to tinkling sheep-bells, and the 6 | Queen's shrill cries to the voice of the shepherd boy--and the 7 | sneeze of the baby, the shriek of the Gryphon, and all the other 8 | queer noises, would change (she knew) to the confused clamour of 9 | the busy farm-yard--while the lowing of the cattle in the distance 10 | would take the place of the Mock Turtle's heavy sobs. 11 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/sample.crontab: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT THIS FILE - edit the master and reinstall. 2 | # (/tmp/crontab.4646 installed on Mon Dec 2 01:36:36 2002) 3 | # (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $) 4 | SHELL=/bin/bash 5 | PATH=/sbin:/bin:/usr/sbin:/usr/bin 6 | MAILTO=klauser@klauser.ch 7 | 8 | 1 * * * 5 /home/ACeSystem/sbin/inquiries_quality.pl 9 | 03,25 20 3-16 * * /home/ACeSystem/sbin/clean_news.pl 10 | 06 22 * * Mou /home/ACeSystem/bin/del_old_ACinventories.pl 11 | 08 22 * * 1-3,6 /home/ACeSystem/bin/dumpACinventories.pl 12 | 99 22 * * 1-3,6 /home/ACeSystem/bin/dump_cust_part_no.pl 13 | 25 22 * * 0-4 /home/ACeSystem/bin/files2ACinventories.pl 2>/dev/null 14 | ### 05 23 * * 0-4 /home/ACeSystem/bin/getACinventory.sh 15 | 05 23 * * 0-4 /home/ACeSystem/bin/getLaser.sh 16 | 50 23 * Oct * /home/ACeSystem/bin/examine_ACinventories.pl 17 | 18 | 19 | 20 | # DO NOT EDIT THIS FILE - edit the master and reinstall. 21 | # (/tmp/crontab.kmSWI17568 installed on Thu Jun 27 12:38:53 2002) 22 | # (Cron version -- $FreeBSD: src/usr.sbin/cron/crontab/crontab.c,v 1.11.2.1 1999/08/29 15:40:42 peter Exp $) 23 | #0 8,10,13 * * 1-5 /usr/home/rich/bldg400/check1e 24 | #10 8,10,13 * * 1-5 /usr/home/rich/bldg400/check1w 25 | #20 8,10,13 * * 1-5 /usr/home/rich/bldg400/check2e 26 | #30 8,10,13 * * 1-5 /usr/home/rich/bldg400/check2w 27 | #40 8,10,13 * * 1-5 /usr/home/rich/bldg400/check3e 28 | #50 8,10,13 * * 1-5 /usr/home/rich/bldg400/check3w 29 | #0 6-17 * * 1-5 /usr/home/rich/switch/checkit 30 | 0 6-17 * * 1-5 /usr/home/rich/switch/check/checkM 31 | 30 5 * * 1-5 /usr/home/rich/switch/check/checkB 32 | 30 11 * * 1-5 /usr/home/rich/switch/check/checkR 33 | 0,5,10,15,20,25,30,35,40,45,50,55 5-18 * * 1-5 /usr/home/rich/cisco/utils 34 | 55 4 * * 1-5 /usr/home/rich/cisco/mailit 35 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/state.capitals.txt: -------------------------------------------------------------------------------- 1 | Alabama Montgomery 2 | Alaska Juneau 3 | Arizona Phoenix 4 | Arkansas Little-Rock 5 | California Sacramento 6 | Colorado Denver 7 | Connecticut Hartford 8 | Delaware Dover 9 | Florida Tallahassee 10 | Georgia Atlanta 11 | Hawaii Honolulu 12 | Idaho Boise 13 | Illinois Springfield 14 | Indiana Indianapolis 15 | Iowa Des-Moines 16 | Kansas Topeka 17 | Kentucky Frankfort 18 | Louisiana Baton-Rouge 19 | Maine Augusta 20 | Maryland Annapolis 21 | Massachusetts Boston 22 | Michigan Lansing 23 | Minnesota St.-Paul 24 | Mississippi Jackson 25 | Missouri Jefferson-City 26 | Montana Helena 27 | Nebraska Lincoln 28 | Nevada Carson-City 29 | New-Hampshire Concord 30 | New-Jersey Trenton 31 | New-Mexico Santa-Fe 32 | New-York Albany 33 | North-Carolina Raleigh 34 | North-Dakota Bismarck 35 | Ohio Columbus 36 | Oklahoma Oklahoma-City 37 | Oregon Salem Portland 38 | Pennsylvania Harrisburg 39 | Rhode-Island Providence 40 | South-Carolina Columbia 41 | South-Dakota Pierre 42 | Tennessee Nashville 43 | Texas Austin 44 | Utah Salt-Lake-City 45 | Vermont Montpelier 46 | Virginia Richmond 47 | Washington Olympia 48 | West-Virginia Charleston 49 | Wisconsin Madison 50 | Wyoming Cheyenne 51 | -------------------------------------------------------------------------------- /Wicked Cool Scripts/text.snippet.txt: -------------------------------------------------------------------------------- 1 | Perhaps one of the most valuable uses of shell scripts is to fix 2 | your particular flavor of Unix and make it more like other flavors, 3 | to bring your commands into conformance or to increase consistency 4 | across different systems. The outsider view of Unix suggests a 5 | nice, uniform command-line experience, helped along by the existence 6 | and compliance with the POSIX standards for Unix, but anyone who's 7 | ever touched more than one computer knows how much they can vary 8 | within these broad parameters. 9 | -------------------------------------------------------------------------------- /bash/.zed/settings.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanshin/bin/251da0aafdd46479e789ab2fe8762ac767ab1662/bash/.zed/settings.json -------------------------------------------------------------------------------- /bash/appender.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | # appender.sh 6 | # 7 | # appender.sh appends a variety of things to the end of a file. 8 | # It is specifically for appending items to the `inbox.md` file 9 | # in my ouroborus wiki. 10 | # 11 | # Flag - Purpose 12 | # -u - append a URL and its description 13 | # -q - append a quote and its source 14 | # -t - append a tweet 15 | # -r - append random text 16 | # -T - append a to do 17 | 18 | # 0 args, return usage 19 | # 1 arg, has to be `-t`, `-T` or `-r` 20 | # 2 args, has to be `-u` or `-q` 21 | 22 | if [[ $# -ne 2 && $# -ne 3 ]]; then 23 | echo "Usage: $0 -u " 24 | echo " : $0 -q " 25 | echo " : $0 -t " 26 | echo " : $0 -r " 27 | echo " : $0 -T " 28 | exit 2 29 | fi 30 | 31 | # Location of inbox.md 32 | inbox_location="$HOME/code/ouroborus/docs/inbox.md" 33 | inboxdayfile="$HOME/code/ouroborus/docs/.inboxday" 34 | 35 | # Date 36 | year=$(date '+%Y') 37 | month=$(date '+%m') 38 | day=$(date '+%d') 39 | 40 | # Add date to inbox, if necessary 41 | inboxday=$(<"$inboxdayfile") 42 | 43 | if [[ "$inboxday" -ne "$day" ]]; then 44 | printf "\n$month/$day/$year\n" >> "$inbox_location" 45 | echo "$day" > "$inboxdayfile" 46 | fi 47 | 48 | # Determine what flag was passed in 49 | case "$1" in 50 | -u) # 51 | echo "* [$3]($2)" >> "$inbox_location" 52 | ;; 53 | -q) # 54 | echo "* $2 ~ $3" >> "$inbox_location" 55 | ;; 56 | -t) # 57 | echo "* $2" >> "$inbox_location" 58 | ;; 59 | -r) # 60 | echo "* $2" >> "$inbox_location" 61 | ;; 62 | -T) # 63 | echo "* [ ] - $2" >> "$inbox_location" 64 | ;; 65 | esac 66 | 67 | 68 | echo "done" 69 | exit 0 70 | 71 | -------------------------------------------------------------------------------- /bash/arch-reboot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | NEXTLINE=0 6 | FIND="" 7 | for I in $(file /boot/vmlinuz*); do 8 | if [ ${NEXTLINE} -eq 1 ]; then 9 | FIND="${I}" 10 | NEXTLINE=0 11 | else 12 | if [ "${I}" = "version" ]; then NEXTLINE=1; fi 13 | fi 14 | done 15 | if [ ! "${FIND}" = "" ]; then 16 | CURRENT_KERNEL=$(uname -r) 17 | if [ ! "${CURRENT_KERNEL}" = "${FIND}" ]; then 18 | echo "Boot required" 19 | fi 20 | fi 21 | -------------------------------------------------------------------------------- /bash/arch-updates.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | updatefile="$HOME/.updatecount" 6 | updatecount=$(checkupdates | wc -l) 7 | 8 | if [ $? -ne 0 ]; then 9 | updatecount="N/A" 10 | fi 11 | 12 | rm -f "$updatefile" 13 | echo "$updatecount" > "$updatefile" 14 | chmod a+rw "$updatefile" 15 | -------------------------------------------------------------------------------- /bash/awscli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # portions based on example at http://prasaddomala.com/configure-multi-factor-authentication-mfa-with-aws-cli/ 3 | 4 | user_profile=default 5 | mfa_profile=mfa 6 | 7 | # nuke the token_exp line from the profile in ~/.aws/config to override and force new token update 8 | exp=$(aws configure get token_exp --profile $mfa_profile) 9 | echo "using expiration of $exp" 10 | now=$(date -u +"%Y-%m-%dT%H:%M:%SZ") 11 | if "$exp" > "$now" ; then 12 | echo "The cofigured token is still valid. Exiting without update -- remove token_exp from config to force update" 13 | exit 1 14 | fi 15 | echo $now 16 | 17 | read -p "token: " token 18 | 19 | mfa=`aws iam list-mfa-devices --profile $user_profile --output text | awk '{print $3}'` 20 | 21 | echo "Using $mfa" 22 | 23 | ​# different versions of the cli seem to release these in different orders so request everything and do a sort based on keys to get a predictable order 24 | read -r keyid exp secret stoken < <(aws sts get-session-token --profile $user_profile --output json --serial-number $mfa --token-code $token | egrep "SecretAccessKey|SessionToken|Expiration|AccessKeyId" | sort | awk '{print $2}' | sed -e "s/\"\,*//g" | paste -sd "\t" -) 25 | 26 | 27 | echo "new keyid: $keyid" 28 | echo "Expires: $exp" 29 | 30 | aws configure set aws_access_key_id "$keyid" --profile $mfa_profile 31 | aws configure set aws_secret_access_key "$secret" --profile $mfa_profile 32 | aws configure set aws_session_token "$stoken" --profile $mfa_profile 33 | aws configure set token_exp "$exp" --profile $mfa_profile 34 | 35 | echo "Profile $mfa_profile configured -- or source ~/.aws/$mfa_profile.tmp" 36 | # alternatively can use these if you source the tmp file: 37 | echo "export AWS_ACCESS_KEY_ID=\"$keyid\"" > ~/.aws/$mfa_profile.tmp #source this as desired 38 | echo "export AWS_SECRET_ACCESS_KEY=\"$secret\"" >> ~/.aws/$mfa_profile.tmp 39 | echo "export AWS_SESSION_TOKEN=\"$stoken\"" >> ~/.aws/$mfa_profile.tmp 40 | -------------------------------------------------------------------------------- /bash/awsmfa.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Sample for getting temp session token from AWS STS 4 | # 5 | # aws --profile youriamuser sts get-session-token --duration 3600 \ 6 | # --serial-number arn:aws:iam::012345678901:mfa/user --token-code 012345 7 | # 8 | # Once the temp token is obtained, you'll need to feed the following environment 9 | # variables to the aws-cli: 10 | # 11 | # export AWS_ACCESS_KEY_ID='KEY' 12 | # export AWS_SECRET_ACCESS_KEY='SECRET' 13 | # export AWS_SESSION_TOKEN='TOKEN' 14 | 15 | AWS_CLI=`which aws` 16 | 17 | if [ $? -ne 0 ]; then 18 | echo "AWS CLI is not installed; exiting" 19 | exit 1 20 | else 21 | echo "Using AWS CLI found at $AWS_CLI" 22 | fi 23 | 24 | # 1 or 2 args ok 25 | if [[ $# -ne 1 && $# -ne 2 ]]; then 26 | echo "Usage: $0 " 27 | echo "Where:" 28 | echo " = Code from virtual MFA device" 29 | echo " = aws-cli profile usually in $HOME/.aws/config" 30 | exit 2 31 | fi 32 | 33 | echo "Reading config..." 34 | if [ ! -r ~/mfa.cfg ]; then 35 | echo "No config found. Please create your mfa.cfg. See README.txt for more info." 36 | exit 2 37 | fi 38 | 39 | AWS_CLI_PROFILE=${2:-default} 40 | MFA_TOKEN_CODE=$1 41 | ARN_OF_MFA=$(grep "^$AWS_CLI_PROFILE" ~/mfa.cfg | cut -d '=' -f2- | tr -d '"') 42 | 43 | echo "AWS-CLI Profile: $AWS_CLI_PROFILE" 44 | echo "MFA ARN: $ARN_OF_MFA" 45 | echo "MFA Token Code: $MFA_TOKEN_CODE" 46 | 47 | echo "Your Temporary Creds:" 48 | aws --profile $AWS_CLI_PROFILE sts get-session-token --duration 129600 \ 49 | --serial-number $ARN_OF_MFA --token-code $MFA_TOKEN_CODE --output text \ 50 | | awk '{printf("export AWS_ACCESS_KEY_ID=\"%s\"\nexport AWS_SECRET_ACCESS_KEY=\"%s\"\nexport AWS_SESSION_TOKEN=\"%s\"\nexport AWS_SECURITY_TOKEN=\"%s\"\n",$2,$4,$5,$5)}' | tee ~/.token_file 51 | -------------------------------------------------------------------------------- /bash/awsps1: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | IDENTITY=$(aws sts get-caller-identity 2>/dev/null) 6 | 7 | # { "UserId": "AROA37OUXEIOJBJEKISVP:mhn", 8 | # "Account": "823469220380", 9 | # "Arn": "arn:aws:sts::823469220380:assumed-role/Administrator/mhn" 10 | # } 11 | 12 | ACCOUNT=$(echo $IDENTITY | jq .Account | sed -e 's/^"//' -e 's/"$//') 13 | ROLE=$(echo $IDENTITY | jq .Arn | cut -d"/" -f2-2 | tr '"' ' ') 14 | 15 | # Lookup account name using $ACCOUNT 16 | case $ACCOUNT in 17 | "448491663515") 18 | NAME="KSU" 19 | ;; 20 | "823469220380") 21 | NAME="Audit" 22 | ;; 23 | "929355877128") 24 | NAME="dev" 25 | ;; 26 | "758488095288") 27 | NAME="Log" 28 | ;; 29 | "249588034506") 30 | NAME="Master" 31 | ;; 32 | "529763884941") 33 | NAME="Prod" 34 | ;; 35 | "654766883003") 36 | NAME="Sandbox" 37 | ;; 38 | "356835234430") 39 | NAME="Shared" 40 | ;; 41 | "529592246862") 42 | NAME="Transit" 43 | ;; 44 | *) 45 | NAME="Unknown" 46 | ;; 47 | esac 48 | 49 | echo "$ROLE / $NAME" 50 | -------------------------------------------------------------------------------- /bash/awswho: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | # Colors 6 | RED='\033[0;31m' 7 | BLUE='\033[0;34m' 8 | GREEN='\033[0;32m' 9 | NC='\033[0m' 10 | 11 | IDENTITY=$(aws sts get-caller-identity 2>/dev/null) 12 | 13 | # { "UserId": "AROA37OUXEIOJBJEKISVP:mhn", 14 | # "Account": "823469220380", 15 | # "Arn": "arn:aws:sts::823469220380:assumed-role/Administrator/mhn" 16 | # } 17 | 18 | ACCOUNT=$(echo $IDENTITY | jq .Account | sed -e 's/^"//' -e 's/"$//') 19 | ROLE=$(echo $IDENTITY | jq .Arn | cut -d"/" -f2-3 | tr '"' ' ') 20 | KUBE=$(egrep "current-context" $HOME/.kube/config | cut -d/ -f2) 21 | 22 | # Lookup account name using $ACCOUNT 23 | case $ACCOUNT in 24 | "448491663515") 25 | NAME="KSU" 26 | ;; 27 | "823469220380") 28 | NAME="Audit" 29 | ;; 30 | "929355877128") 31 | NAME="dev" 32 | ;; 33 | "758488095288") 34 | NAME="Log" 35 | ;; 36 | "249588034506") 37 | NAME="Master" 38 | ;; 39 | "529763884941") 40 | NAME="Prod" 41 | ;; 42 | "654766883003") 43 | NAME="Sandbox" 44 | ;; 45 | "356835234430") 46 | NAME="Shared" 47 | ;; 48 | "529592246862") 49 | NAME="Transit" 50 | ;; 51 | *) 52 | NAME="Unknown" 53 | ;; 54 | esac 55 | 56 | echo -e "You are: ${BLUE}$ROLE${NC} in account: ${BLUE}$NAME${NC} (${RED}$ACCOUNT${NC}) with a Kubernetes context of ${GREEN}$KUBE${NC}" 57 | -------------------------------------------------------------------------------- /bash/backup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | set -o pipefail 6 | 7 | # Enable debug mode, by running script as TRACE=1 ./script.sh 8 | if [[ "${TRACE-0}" == "1" ]]; then 9 | set -o trace 10 | fi 11 | 12 | 13 | main() { 14 | 15 | filename="/Volumes/WasabiRsync/backup/backup_$(date +%F).log" 16 | touch "$filename" 17 | echo "backing up code directory" 18 | rsync -azh --progress --delete --log-file="$filename" --filter="- *.DS_Store" ~/code /Volumes/WasabiRsync/backup/ 19 | echo "backing up Desktop directory" 20 | rsync -azh --progress --delete --log-file="$filename" --filter="- *.DS_Store" ~/Desktop /Volumes/WasabiRsync/backup/ 21 | echo "backing up Documents directory" 22 | rsync -azh --progress --delete --log-file="$filename" --filter="- *.DS_Store" ~/Documents /Volumes/WasabiRsync/backup/ 23 | echo "backing up Downloads directory" 24 | rsync -azh --progress --delete --log-file="$filename" --filter="- *.DS_Store" ~/Downloads /Volumes/WasabiRsync/backup/ 25 | echo "backing up src directory" 26 | rsync -azh --progress --delete --log-file="$filename" --filter="- *.DS_Store" ~/src /Volumes/WasabiRsync/backup/ 27 | } 28 | 29 | main "$@" 30 | -------------------------------------------------------------------------------- /bash/backup_2023-02-16.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanshin/bin/251da0aafdd46479e789ab2fe8762ac767ab1662/bash/backup_2023-02-16.log -------------------------------------------------------------------------------- /bash/buildAll.sh: -------------------------------------------------------------------------------- 1 | echo checkout idm from head 2 | rm -rf idm 3 | cvs -Q co idm 4 | echo copy snapshot properties file 5 | echo cp project.properties idm/project.properties 6 | cp project.properties idm/project.properties 7 | 8 | echo starting build at on veld 9 | pwd 10 | 11 | cd idm 12 | echo 13 | echo cd idm/commons/config 14 | cd commons 15 | cd core 16 | #echo maven 2>&1 17 | #maven 2>&1 18 | echo cd ../config 19 | cd ../config 20 | echo maven 2>&1 21 | maven 2>&1 22 | echo cd ../process-scheduler 23 | cd ../process-scheduler 24 | echo maven 2>&1 25 | maven 2>&1 26 | echo cd ../lazi 27 | cd ../lazi 28 | echo maven 2>&1 29 | maven 2>&1 30 | echo cd ../request-framework 31 | cd ../request-framework 32 | echo maven 2>&1 33 | maven 2>&1 34 | echo cd ../sanity 35 | cd ../sanity 36 | echo maven 2>&1 37 | maven 2>&1 38 | #echo cd ../struts2 39 | #cd ../struts2 40 | #echo maven 2>&1 41 | #maven 2>&1 42 | echo cd ../../keas 43 | cd ../../keas 44 | echo maven 2>&1 45 | maven 2>&1 46 | echo cd ../ws-clients 47 | cd ../ws-clients 48 | echo maven 2>&1 49 | maven 2>&1 50 | echo cd ../webapps/portal-services 51 | cd ../webapps 52 | cd portal-services 53 | echo maven 2>&1 54 | maven 2>&1 55 | echo cd ../keas-ws 56 | cd ../keas-ws 57 | echo maven 2>&1 58 | maven 2>&1 59 | echo cd ../keas-events 60 | cd ../keas-events 61 | echo maven 2>&1 62 | maven 2>&1 63 | echo cd ../ksuAlerts 64 | cd ../ksuAlerts 65 | echo maven 2>&1 66 | maven 2>&1 67 | echo cd ../eProfile 68 | cd ../eProfile 69 | echo maven 2>&1 70 | maven 2>&1 71 | echo cd ../KEAS-support 72 | cd ../KEAS-support 73 | echo maven 2>&1 74 | maven 2>&1 75 | echo cd ../deploy/services 76 | cd ../deploy/services 77 | echo maven 2>&1 78 | maven 2>&1 79 | echo cd ../../../ 80 | cd ../../../ 81 | pwd 82 | 83 | -------------------------------------------------------------------------------- /bash/check_service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if a service name was provided 4 | if [ -z "$1" ]; then 5 | echo "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | SERVICE_NAME="$1" 10 | 11 | # Check if the service is running 12 | if systemctl is-active --quiet "$SERVICE_NAME"; then 13 | echo "$SERVICE_NAME is already running." 14 | else 15 | echo "$SERVICE_NAME is not running. Starting it now..." 16 | sudo systemctl start "$SERVICE_NAME" 17 | 18 | # Verify if it started successfully 19 | if systemctl is-active --quiet "$SERVICE_NAME"; then 20 | echo "$SERVICE_NAME started successfully." 21 | else 22 | echo "Failed to start $SERVICE_NAME." 23 | fi 24 | fi 25 | -------------------------------------------------------------------------------- /bash/compare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Function to extract package names from file 4 | extract_package_names() { 5 | awk '{print $1}' "$1" | sort | uniq 6 | } 7 | 8 | # Function to compare two lists and find missing elements 9 | compare_lists() { 10 | list1=($(extract_package_names "$1")) 11 | list2=($(extract_package_names "$2")) 12 | 13 | missing_in_list2=() 14 | missing_in_list1=() 15 | 16 | # Compare lists 17 | i=0 18 | j=0 19 | while [[ $i -lt ${#list1[@]} && $j -lt ${#list2[@]} ]]; do 20 | if [[ "${list1[$i]}" < "${list2[$j]}" ]]; then 21 | missing_in_list2+=("${list1[$i]}") 22 | ((i++)) 23 | elif [[ "${list1[$i]}" > "${list2[$j]}" ]]; then 24 | missing_in_list1+=("${list2[$j]}") 25 | ((j++)) 26 | else 27 | ((i++)) 28 | ((j++)) 29 | fi 30 | done 31 | 32 | # Any remaining elements in list1 are missing in list2 33 | while [[ $i -lt ${#list1[@]} ]]; do 34 | missing_in_list2+=("${list1[$i]}") 35 | ((i++)) 36 | done 37 | 38 | # Any remaining elements in list2 are missing in list1 39 | while [[ $j -lt ${#list2[@]} ]]; do 40 | missing_in_list1+=("${list2[$j]}") 41 | ((j++)) 42 | done 43 | 44 | # Output results 45 | printf "Packages missing in list 2:\n" 46 | printf "%s\n" "${missing_in_list2[@]}" 47 | 48 | printf "\nPackages missing in list 1:\n" 49 | printf "%s\n" "${missing_in_list1[@]}" 50 | } 51 | 52 | # Check if two file names are provided as arguments 53 | if [ $# -ne 2 ]; then 54 | echo "Usage: $0 " 55 | exit 1 56 | fi 57 | 58 | # Check if files exist 59 | if [ ! -f "$1" ]; then 60 | echo "File $1 does not exist" 61 | exit 1 62 | fi 63 | 64 | if [ ! -f "$2" ]; then 65 | echo "File $2 does not exist" 66 | exit 1 67 | fi 68 | 69 | compare_lists "$1" "$2" 70 | 71 | -------------------------------------------------------------------------------- /bash/daily-note.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | # note.sh 7 | # Creates a new daily note file, if not found, and adds timestamp 8 | # ahead of insertion point. If note is closed without saving, the 9 | # timestamp is not saved. 10 | # 11 | 12 | # noteFilename="$HOME/Nextcloud/documents/notes/note-$(date +%Y-%m-%d).md" 13 | noteFilename="$HOME/Documents/notes/daily/note-$(date +%Y-%m-%d).md" 14 | 15 | if [ ! -f "$noteFilename" ]; then 16 | echo "# Notes for $(date +%Y-%m-%d)" > "$noteFilename" 17 | fi 18 | 19 | nvim -c "norm Go" \ 20 | -c "norm Go## $(date +"%I:%M %p")" \ 21 | -c "norm G2o" \ 22 | -c "norm zz" \ 23 | -c "startinsert" "$noteFilename" 24 | 25 | 26 | -------------------------------------------------------------------------------- /bash/df.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ ! -z "$*" ]; then 4 | echo "this is ~/bin/df, use /bin/df" 5 | exit 1 6 | fi 7 | 8 | protect=`mount | grep -v "read-only" | grep "protect" | cut -f 3 -w` 9 | nosuid=`mount | grep -v "read-only" | grep "nosuid" | cut -f 3 -w` 10 | 11 | /bin/df -PH $protect $nosuid | cut -f 2- -w 12 | -------------------------------------------------------------------------------- /bash/du_filetype: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | find . -type f \ 4 | —name “*.mp4” \ 5 | -o -name “*.m4v” \ 6 | -o -name “*.mp3” \ 7 | -o -name “*.wav” \ 8 | -o -name “*.flv” \ 9 | -o -name “*.mpeg” \ 10 | -o -name *.mpg” \ 11 | -o -name “*.mpe” \ 12 | -o -name “*.rm” \ 13 | -o -name “*.rv” \ 14 | -o -name “*.ra” \ 15 | -o -name “*.wmv” \ 16 | -o -name “*.wma” \ 17 | -o -name “*.avi” \ 18 | -o -name “*.mov” \ 19 | -o -name “*.asf” \ 20 | -o -name “*.ogg” \ 21 | -o -name “*.webm” -printf "%f %s\n" | 22 | awk '{ 23 | PARTSCOUNT=split( $1, FILEPARTS, "." ); 24 | EXTENSION=PARTSCOUNT == 1 ? "NULL" : FILEPARTS[PARTSCOUNT]; 25 | FILETYPE_MAP[EXTENSION]+=$2 26 | } 27 | END { 28 | for( FILETYPE in FILETYPE_MAP ) { 29 | print FILETYPE_MAP[FILETYPE], FILETYPE; 30 | } 31 | }' | sort -n 32 | -------------------------------------------------------------------------------- /bash/explain: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # https://github.com/schneems/explain_shell 4 | 5 | # base url with first command already injected 6 | # $ explain tar 7 | # => http://explainshel.com/explain/tar?args= 8 | url="http://explainshell.com/explain/$1?args=" 9 | 10 | # removes $1 (tar) from arguments ($@) 11 | shift; 12 | 13 | # iterates over remaining args and adds builds the rest of the url 14 | for i in "$@"; do 15 | url=$url"$i""+" 16 | done 17 | 18 | # opens url in browser 19 | open "$url" 20 | -------------------------------------------------------------------------------- /bash/finddirtygit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | ############################################################################## 6 | # Find any dirty git projects in the current working directory 7 | # and recursively beneath this directory 8 | # 9 | # USAGE: 10 | # finddirtygit 11 | # Quiet mode that outputs only the project that is dirty 12 | # finddirtygit -v 13 | # Verbose mode that outputs what files are dirty 14 | ############################################################################## 15 | 16 | # Find all directories that have a .git directory in them 17 | for gitprojpath in $(find . -type d -name .git | sed "s/\/\.git//"); do 18 | # Save the current working directory before CDing for git's purpose 19 | pushd . >/dev/null 20 | 21 | # Switch to the git-enabled project directory 22 | cd "$gitprojpath" 23 | 24 | # Are there any changed files in the status output? 25 | isdirty=$(git status -s | grep "^.*") 26 | if [ -n "$isdirty" ]; then 27 | # Should output be verbose? 28 | if [ "$1" = "-v" ]; then 29 | echo 30 | echo "DIRTY: $gitprojpath" 31 | git status -s 32 | # Or should output be quiet? 33 | else 34 | echo "DIRTY: $gitprojpath" 35 | fi 36 | fi 37 | # Return to the starting directory, suppressing the output 38 | popd >/dev/null 39 | done 40 | -------------------------------------------------------------------------------- /bash/fixBrewLionPostgres.sh: -------------------------------------------------------------------------------- 1 | # from http://nextmarvel.net/blog/2011/09/brew-install-postgresql-on-os-x-lion/ 2 | BREW_POSTGRES_DIR=`brew info postgres | awk '{print $1"/bin"}' | grep "/postgresql/"` 3 | LION_POSTGRES_DIR=`which postgres | xargs dirname` 4 | LION_PSQL_DIR=`which psql | xargs dirname` 5 | 6 | sudo mkdir -p $LION_POSTGRES_DIR/archive 7 | sudo mkdir -p $LION_PSQL_DIR/archive 8 | 9 | for i in `ls $BREW_POSTGRES_DIR` 10 | do 11 | if [ -f $LION_POSTGRES_DIR/$i ] 12 | then 13 | sudo mv $LION_POSTGRES_DIR/$i $LION_POSTGRES_DIR/archive/$i 14 | sudo ln -s $BREW_POSTGRES_DIR/$i $LION_POSTGRES_DIR/$i 15 | fi 16 | 17 | if [ -f $LION_PSQL_DIR/$i ] 18 | then 19 | sudo mv $LION_PSQL_DIR/$i $LION_PSQL_DIR/archive/$i 20 | sudo ln -s $BREW_POSTGRES_DIR/$i $LION_PSQL_DIR/$i 21 | fi 22 | done 23 | -------------------------------------------------------------------------------- /bash/gitbranch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | echo 6 | find . -type d -name ".git" -execdir bash -c ' 7 | if [ ! $(git status | grep -o nothing) ] 8 | then 9 | x=$(basename "$PWD") 10 | y=$(dirname "$PWD") 11 | echo -e "\033[1;32m${x}\033[0m (${y})" >&2 12 | git status -s >&2 13 | git branch >&2 14 | echo >&2 15 | fi 16 | ' \; > /dev/null 17 | -------------------------------------------------------------------------------- /bash/gitcmds.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | set -o pipefail 6 | 7 | 8 | main() { 9 | echo "Git aliases " 10 | echo "synced git pull origin $(git mainbranch) --rebase" 11 | echo "update - git pull origin $(git rev-parse --abbrev-ref HEAD) --rebase" 12 | echo "squash - git rebase -v- i $(git mainbranch)" 13 | echo "[pub]lish - push origin HEAD --force-with-lease" 14 | echo "" 15 | } 16 | 17 | main "$@" 18 | -------------------------------------------------------------------------------- /bash/gitted.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | echo 6 | find . -type d -name ".git" -execdir bash -c ' 7 | if [ ! $(git status | grep -o nothing) ] 8 | then 9 | x=$(basename "$PWD") 10 | y=$(dirname "$PWD") 11 | echo -e "\033[1;32m${x}\033[0m (${y})" >&2 12 | git status -s >&2 13 | echo >&2 14 | fi 15 | ' \; > /dev/null 16 | -------------------------------------------------------------------------------- /bash/gitup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BASE_DIR="$1" 4 | 5 | BLUE='\033[1;34m' 6 | NC='\033[m' 7 | 8 | if [[ -z "$BASE_DIR" ]]; then 9 | echo "Usage: $0 " 10 | exit 1 11 | fi 12 | 13 | if [[ ! -d "$BASE_DIR" ]]; then 14 | echo "Error: Directory '$BASE_DIR' does not exist." 15 | exit 1 16 | fi 17 | 18 | for dir in "$BASE_DIR"/*; do 19 | if [[ -d "$dir/.git" ]]; then 20 | echo 21 | echo -e "${BLUE}Updating repository: $dir${NC}" 22 | (cd "$dir" && git update) 23 | else 24 | echo "Skipping: $dir (not a Git repository)" 25 | fi 26 | done 27 | -------------------------------------------------------------------------------- /bash/go_installer.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | set -o pipefail 3 | 4 | # go_installer.sh 5 | # 6 | # go_installer.sh collects the series of commands necessary to update (install) 7 | # Go on a Raspberry Pi. 8 | # 9 | export GOLANG="$(curl https://golang.org/dl/|grep linux-armv6l|grep -v beta|head -1|awk -F\> {'print $3'}|awk -F\< {'print $1'})" 10 | wget https://golang.org/dl/$GOLANG 11 | sudo tar -C /usr/local -xzf $GOLANG 12 | rm $GOLANG 13 | unset GOLANG 14 | -------------------------------------------------------------------------------- /bash/handbrakecli: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #input="$1" 3 | #shift 4 | #output="$1" 5 | #shift 6 | 7 | # HandBrakeCLI -i "$input" --preset=quix -Y 540 -o $output.m4v 8 | 9 | #HandBrakeCLI -i "$input" --preset=Normal -x ref=4 -q 23 -E copy,faac -B auto,128 -O -e x264 -o Strange-cli-23.mkv 10 | 11 | qual="-q 17" 12 | 13 | if [ "$1" == "18" ]; then 14 | qual="-q 18" 15 | shift 16 | fi 17 | 18 | outadd="" 19 | if [ "$1" == "dvd" ]; then 20 | shift 21 | qual="-t $1 $qual" 22 | outadd="track$1-" 23 | shift 24 | fi 25 | 26 | audio="1,2,3,4,5,6,7,8,9,10" 27 | 28 | if [ "$1" != "${1#astrip:}" ]; then 29 | audio="${1#astrip:}" 30 | shift 31 | fi 32 | 33 | if [ "$1" == "echo" ]; then 34 | echo=1 35 | shift 36 | fi 37 | 38 | for i in "$@"; do 39 | #echo HandBrakeCLI -i "$i" --preset=Normal -x ref=4 $qual -E copy --audio-copy-mask ac3,dts --audio-fallback ffac3 -O -e x264 --subtitle scan,1,2,3,4,5,6,7,8,9,10 -a $audio -o "$i-out.mkv" 40 | # HandBrakeCLI -i "$i" --preset=Normal -x ref=4 $qual -E copy --audio-copy-mask ac3,dts --audio-fallback ffac3 -O -e x264 --subtitle scan,1,2,3,4,5,6,7,8,9,10 -a $audio -o "$i-out.mkv" 41 | echo HandBrakeCLI -i "$i" --preset=Normal -x ref=4 "$qual" -E copy --audio-copy-mask ac3 --audio-fallback ffac3 -X 1920 -Y 1080 -O -e x264 --subtitle 1,2,3,4,5,6,7,8,9,10 -a "$audio" -o "$i-${outadd}out.mkv" 42 | if [ "$echo" == "" ]; then 43 | HandBrakeCLI -i "$i" --preset=Normal -x ref=4 "$qual" -E copy --audio-copy-mask ac3 --audio-fallback ffac3 -X 1920 -Y 1080 -O -e x264 --subtitle 1,2,3,4,5,6,7,8,9,10 -a "$audio" -o "$i-${outadd}out.mkv" 44 | fi 45 | done 46 | 47 | # vim: ft bash 48 | -------------------------------------------------------------------------------- /bash/headtail.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | (head "$1" && echo "---" && tail "$1") | less 6 | -------------------------------------------------------------------------------- /bash/help.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### 4 | ### my-script -- does something 5 | ### 6 | ### Usage: 7 | ### my-script 8 | ### 9 | ### Options: 10 | ### Input file to read. 11 | ### Output file to write. Use '-' for stdout. 12 | ### -h Show this message. 13 | ### 14 | 15 | help() { 16 | # sed -En 's/^### ?//;T;p' "$0" 17 | /usr/local/Cellar/gnu-sed/4.8/gnu-sed -rn 's/^### ?//;T;p' "$0" 18 | } 19 | 20 | if [[ $# == 0 ]] || [[ $1 == "-h" ]]; then 21 | help 22 | exit 1 23 | fi 24 | 25 | -------------------------------------------------------------------------------- /bash/hpost.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # hpost.sh - Creates a new blog posting for the Hugo based site at $BLOG 4 | # Expected to get a string for title. Script will replace spaces with dashes 5 | # and append the `.md` file type. Finally it will open the new file in Neovim 6 | 7 | # So that when a command fails, bash exits instead of continuing with the rest of the script. 8 | set -o errexit 9 | 10 | # This will make the script fail, when accessing an unset variable. Saves from horrible unintended consequences, with typos in variable names. 11 | # When you want to access a variable that may or may not have been set, use "${VARNAME-}" instead of "$VARNAME", and you’re good. 12 | set -o nounset 13 | 14 | # This will ensure that a pipeline command is treated as failed, even if one command in the pipeline fails. 15 | set -o pipefail 16 | 17 | # People can now enable debug mode, by running your script as TRACE=1 ./script.sh instead of ./script.sh. 18 | if [[ "${TRACE-0}" == "1" ]]; then 19 | set -o trace 20 | fi 21 | 22 | # Check if the first arg is -h or --help or help or just h or even -help, and in all these cases, print help text and exit. 23 | if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then 24 | echo 'Usage: ./hpost.sh "Title of New Posting" ' 25 | exit 26 | fi 27 | 28 | DIR="${HOME}/code/hugo/blog" 29 | cd "$(dirname "$DIR")" 30 | 31 | main() { 32 | echo "Creating new posting..." 33 | $(hugo new posts/$(echo "$*" | sed 's/ /-/g').md) 34 | $(nvim) 35 | } 36 | 37 | main "$@" 38 | -------------------------------------------------------------------------------- /bash/idquery.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Prompt for LDAP connection credentials 4 | read -p "Enter LDAP Username cn= : " ldap_user 5 | read -s -p "Enter LDAP Password: " ldap_password 6 | echo # Move to a new line after password input 7 | 8 | if [ -z "$ldap_user" ] || [ -z "$ldap_password" ]; then 9 | echo "Error: LDAP username and password are required." 10 | exit 1 11 | fi 12 | 13 | if [ "$#" -ne 1 ]; then 14 | echo "Usage: $0 " 15 | exit 1 16 | fi 17 | 18 | input_file="$1" 19 | mapping_file="directory-mapping" 20 | 21 | while IFS= read -r id; do 22 | ldap_result=$(ldapsearch -x -LLL -h ome-openldap-p-app-05.prod.aws.ksu.edu -D "cn=$ldap_user,dc=k-state,dc=edu" -w "$ldap_password" -b "ou=People,dc=k-state,dc=edu" "(uid=$id)") 23 | 24 | # Check if the LDAP query returned any results 25 | if [ -n "$ldap_result" ]; then 26 | display_name=$(echo "$ldap_result" | awk -F': ' '/displayName:/ {print $2}') 27 | affiliation=$(echo "$ldap_result" | grep "EMPLOYEE_CURRENT" | awk -F': ' '/ksuPersonAffiliations:/ {print $2}') 28 | mappings=$(grep "$id" "$mapping_file" | wc -l) 29 | printf "ID: %-20s Name: %-30s Affiliation: %-20s Mapping: %-4s \n" "$id" "$display_name" "$affiliation" "$mappings" 30 | # echo "ID: $id, DisplayName: $display_name, Affiliation: $affiliation, Mappings: $mappings" 31 | else 32 | mappings=$(grep "$id" "$mapping_file" | wc -l) 33 | printf "ID: %-20s Name: %-30s Affiliation: %-20s Mapping: %-4s \n" "$id" "NOT FOUND IN LDAP" "NONE" "$mappings" 34 | # echo "ID: $id not found in LDAP" 35 | fi 36 | done < "$input_file" 37 | -------------------------------------------------------------------------------- /bash/inout.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | # created by chris helming. 6 | # chris dot helming at gmail 7 | 8 | # get the current number of bytes in and bytes out 9 | myvar1=$(netstat -ib | grep -e "en1" -m 1 | awk '{print $7}') # bytes in 10 | myvar3=$(netstat -ib | grep -e "en1" -m 1 | awk '{print $10}') # bytes out 11 | 12 | #wait one second 13 | sleep 1 14 | 15 | # get the number of bytes in and out one second later 16 | myvar2=$(netstat -ib | grep -e "en1" -m 1 | awk '{print $7}') # bytes in again 17 | myvar4=$(netstat -ib | grep -e "en1" -m 1 | awk '{print $10}') # bytes out again 18 | 19 | # find the difference between bytes in and out during that one second 20 | subin=$myvar2-$myvar1 21 | subout=$myvar4-$myvar3 22 | 23 | # convert bytes to kilobytes 24 | kbin=$(echo "scale=2; $subin/1024;" | bc) 25 | kbout=$(echo "scale=2; $subout/1024;" | bc) 26 | 27 | # print the results 28 | # echo "\xe2\x86\x91 $kbin Kb/sec" 29 | echo "> $kbin Kb/sec" 30 | echo "< $kbout Kb/sec" 31 | -------------------------------------------------------------------------------- /bash/inpath: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # inpath -- Verifies that a specified program is either valid as is 4 | # or can be found in the PATH directory list 5 | 6 | in_path() 7 | { 8 | # Given a command and the PATH, tried to find the command. Returns 0 if 9 | # found and executable; 1 if not. Note that this temporarily modifies 10 | # the IFS (internal field separator) but restores it upon completion. 11 | 12 | cmd=$1 13 | ourpath=$2 14 | result=1 15 | oldIFS=$IFS 16 | IFS=":" 17 | 18 | for directory in $ourpath 19 | do 20 | if [[ -x $directory/$cmd ]] ; then 21 | result=0 # If we're here, we found the command. 22 | fi 23 | done 24 | 25 | IFS=$oldIFS 26 | return $result 27 | } 28 | 29 | checkForCmdInPath() 30 | { 31 | var=$1 32 | 33 | if [ "$var" != "" ] ; then 34 | if [ "${var:0:1}" = "/" ] ; then 35 | if [ ! -x $var ] ; then 36 | return 1 37 | fi 38 | elif ! in_path $var "$PATH" ; then 39 | return 2 40 | fi 41 | fi 42 | } 43 | 44 | # if [ $# -ne 1 ] ; then 45 | # echo "Usage $0 command" >&2 46 | # exit 1 47 | # fi 48 | 49 | # checkForCmdInPath "$1" 50 | # case $? in 51 | # 0 ) echo "$1 found in PATH" ;; 52 | # 1 ) echo "$1 not found or not executable" ;; 53 | # 2 ) echo "$1 not found in PATH" ;; 54 | # esac 55 | 56 | # exit 0 57 | -------------------------------------------------------------------------------- /bash/lilypond: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec /Applications/LilyPond.app/Contents/Resources/bin/lilypond "$@" 3 | -------------------------------------------------------------------------------- /bash/mfa.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # create filename variable 4 | FILENAME=$HOME/.aws/credentials 5 | 6 | # clear FILENAME of previous contents 7 | > $FILENAME 8 | 9 | # save default key information for mfa command 10 | echo "[default]" >> $FILENAME 11 | echo "aws_access_key_id = FIXME" >> $FILENAME 12 | echo "aws_secret_access_key = FIXME" >> $FILENAME 13 | 14 | # prompt for mfa token 15 | echo "Enter MFA code" 16 | read mfacode 17 | 18 | # run aws token command 19 | result=$(aws sts get-session-token --serial-number FIXME --token-code $mfacode) 20 | 21 | # clear file again and store new keys 22 | > $FILENAME 23 | 24 | access_key_id=$(echo $result | awk '{print $11}' | tr -d '"' | tr -d ',') 25 | secret_access_key=$(echo $result | awk '{print $5}' | tr -d '"' | tr -d ',') 26 | session_tokem=$(echo $result | awk '{ptint $7}' | tr -d '"' |tr -d ',') 27 | 28 | echo >> $FILENAME 29 | echo "[default]" >> $FILENAME 30 | echo "aws_access_key_id = $aws_access_key_id" >> $FILENAME 31 | echo "aws_secret_access_key = $secret_access_key" >> $FILENAME 32 | echo "aws_session_token = $session_token" >> $FILENAME 33 | 34 | echo "MFA session established" 35 | -------------------------------------------------------------------------------- /bash/mosh.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | export LC_ALL=en.US.UTF-8 3 | export LANG=en_US.UTF-8 4 | /usr/bin/mosh-server 5 | -------------------------------------------------------------------------------- /bash/myip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | # 6 | # script to show public IP address 7 | # from: http://lifehacker.com/5194123/display-your-public-ip-address-in-the-shell-prompt 8 | # 20090402 9 | 10 | curl -s myip.dk | grep '"Box"' | grep -E -o '[0-9.]+' 11 | -------------------------------------------------------------------------------- /bash/ng: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ngrok_host=${NGROK_HOST:-ngrok.com} 4 | tmux_user=${TMUX_USER:-$USER} 5 | 6 | if [ ! $(command -v ngrok) ]; then 7 | echo "You must install https://ngrok.com to use this script." 8 | exit 1 9 | fi 10 | 11 | help(){ 12 | echo "Usage: $command [options]\n" 13 | echo "Subcommands:" 14 | echo " connect Connect ngrok reverse tunnel" 15 | echo " ssh Display ssh command to connect through" 16 | echo " ngrok tunnel" 17 | echo "" 18 | } 19 | 20 | connect(){ 21 | if [ $@ ]; then 22 | ngrok $@ 23 | else 24 | ngrok --proto=tcp 22 25 | fi 26 | } 27 | 28 | ssh(){ 29 | port=$(tunnel_port) 30 | 31 | if [ ! -z $port ]; then 32 | ssh_command="ssh -p $port $tmux_user@$ngrok_host" 33 | echo $ssh_command 34 | else 35 | echo "Tunnel with TCP forwarding doesn't seem to be connected." 36 | fi 37 | } 38 | 39 | tunnel_port(){ 40 | tunnel_info_endpoint="http://localhost:4040/http/in" 41 | search_string="tcp://$ngrok_host" 42 | port_strip_regex="s/^.*$ngrok_host:\([0-9]*\).*$/\1/" 43 | 44 | curl -s $tunnel_info_endpoint | grep $search_string | sed $port_strip_regex 45 | } 46 | 47 | subcommand=$1 48 | case $subcommand in 49 | '' | '-h' | '--help') 50 | help ;; 51 | *) 52 | shift 53 | ${subcommand} $@ 54 | ;; 55 | esac 56 | -------------------------------------------------------------------------------- /bash/nicenumber: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # nicenumber -- Given a number, shows it in comma-separated form. Expects DD 4 | # (decimal point delimiter) and TD (thousands delimiter) to be instantiated. 5 | # Instantiates nicenum or, if a second arg is specified, the output is 6 | # echoed to stdout. 7 | 8 | nicenumber() 9 | { 10 | # Note that we assume that '.' is the decimal separator in the INPUT value 11 | # to this scrip. The decimal separator in the output value is '.' unless 12 | # specified by the user with the -d flag. 13 | 14 | integer=$(echo $1 | cut -d. -f1) # Left of decimal 15 | decimal=$(echo $1 | cut -d. -f2) # Right of decimal 16 | 17 | # Check if the number has more then the integer part. 18 | if [ "$decimal" != "$1" ] ; then 19 | # There's a fractional part, so let's include it. 20 | result="${DD:= '.'}$decimal" 21 | fi 22 | 23 | thousands=$integer 24 | 25 | while [ $thousands -gt 999 ] ; do 26 | remainder=$(($thousands % 1000)) # Last three significant digits 27 | 28 | # We need 'remainder' to be three digits. Do we need to add zeros? 29 | while [ ${#remainder} -lt 3 ] ; do # Force leading zeros 30 | remainder="0$remainder" 31 | done 32 | 33 | result="${TD:=","}${remainder}${result}" # Builds right to left 34 | thousands=$(($thousands / 1000)) # To left of remainder, if any 35 | done 36 | 37 | nicenum="${thousands}${result}" 38 | if [ ! -z $2 ] ; then 39 | echo $nicenum 40 | fi 41 | } 42 | 43 | DD='.' # Decimal point delimiter, to separate whole nd fractional values 44 | TD="," # Thousands delimiter, to separate every three digits 45 | 46 | # Begin Main Script 47 | # ================= 48 | 49 | while getopts "d:t:" opt ; do 50 | case $opt in 51 | d ) DD="$OPTARG" ;; 52 | t ) TD="$OPTARG" ;; 53 | esac 54 | done 55 | shift $(($OPTIND - 1)) 56 | 57 | # Input validation 58 | if [ $# -eq 0 ] ; then 59 | echo "Usage: $(basename $0) [-d c] [-t c] number" 60 | echo " -d specifies the decimal point delimiter" 61 | echo " -t specifies the thousands delimiter" 62 | exit 0 63 | fi 64 | 65 | nicenumber $1 1 # Second arg forces nicenumber to 'echo' output. 66 | 67 | exit 0 68 | -------------------------------------------------------------------------------- /bash/nocaps: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This temporarily remaps the CapsLock key to a Control key. 4 | # The keyboard will return to the previous settings after a reboot. 5 | # The Linux console and the X Windows system each handle key presses separately 6 | # so each must be remapped separately. First remap the X keyboard since this 7 | # does not require root access. 8 | 9 | # Remap the Capslock key to a Control key for X Windows 10 | if type setxkbmap >/dev/null @>&1; then 11 | setxkbmap -layout us -option ctrl:nocaps 2>/dev/null 12 | fi 13 | 14 | # You need to be root to remap the console keyboard 15 | if [ "$(id -u)" != "0" ]; then 16 | echo "This script is not running as root so" 17 | echo "the console CapsLock cannot be remapped." 18 | echo "Perhaps you forgot to run this under sudo." 19 | echo "Note that this does not effect X. This only" 20 | echo "effects the consoles running on Alt-f1 through" 21 | echo "lt-f6." 22 | exit 2 23 | fi 24 | 25 | # Remap the CapsLock key to a Control key for the console. 26 | (dumpkeys | grep keymaps; echo "keycode 58 = Control") | loadkeys 27 | -------------------------------------------------------------------------------- /bash/note.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [ "z$DEBUG" != "z" ]; then 5 | set -x 6 | fi 7 | 8 | _NOTES_PATH=${NOTES_PATH:-~/Documents/notes} 9 | export FZF_DEFAULT_OPTS="-m --ansi --preview-window 'right:70%' --preview 'bat --color=always --style=header,grid --line-range :300 ${_NOTES_PATH}/{}'" 10 | 11 | [ -d ${_NOTES_PATH} ] || mkdir ${_NOTES_PATH} 12 | 13 | if [ ! -z "${1:-""}" ]; then 14 | case "$1" in 15 | "last"|"-") 16 | $EDITOR $(find ${_NOTES_PATH} -iname '*.md' | sort | tail -n1) 17 | ;; 18 | "search") 19 | shift 20 | files=$(rg --files-with-matches "$@" ${_NOTES_PATH}) 21 | if [ ! -z "$files" ]; then 22 | if [ $(wc -l <<< "$files") = "1" ]; then 23 | $EDITOR $files 24 | else 25 | files=$(while read file; do basename $file; done <<< "$files" | fzf | while read file; do echo "${_NOTES_PATH}/$file"; done) 26 | if [ ! -z "$files" ]; then 27 | $EDITOR $files 28 | fi 29 | fi 30 | fi 31 | ;; 32 | *) 33 | >&2 echo "note [search|last]" 34 | exit 1 35 | ;; 36 | esac 37 | 38 | exit 39 | fi 40 | 41 | file=$(mktemp) 42 | mv "$file"{,.md} 43 | file="${file}.md" 44 | mtime_in=$(date -r "$file" "+%s") 45 | if ${EDITOR:-/usr/bin/vim} $file; then 46 | mtime_out=$(date -r "$file" "+%s") 47 | if [ $mtime_in -eq $mtime_out ]; then 48 | >&2 echo 'No changes to file. Discarding note.' 49 | rm $file 50 | exit 1 51 | fi 52 | else 53 | >&2 echo '$EDITOR returned a non-zero exit code. Discarding note.' 54 | rm $file 55 | exit 1 56 | fi 57 | 58 | slug=$(sed '/[^[:blank:]]/q;d' < "$file" | 59 | sed -e 's/[^a-zA-Z0-9]/-/g' | 60 | sed -E 's/[\-]+/-/g' | 61 | sed -e 's/^-//g' | 62 | sed -e 's/-$//g' | 63 | tr '[[:upper:]]' '[[:lower:]]') 64 | 65 | dest="${_NOTES_PATH}/$(date -r "$file" "+%Y%m%d")-${slug:-untitled-note}" 66 | suffix="" 67 | while [ -e "${dest}${suffix}.md" ]; do 68 | suffix=$((${suffix:-0} - 1)) 69 | done 70 | 71 | mv "$file" "${dest}${suffix}.md" 72 | echo "Stored note at \"${dest}${suffix}.md\"." 73 | -------------------------------------------------------------------------------- /bash/nsshfs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function __nsshfs_usage() { 4 | echo -e "Usage: nsshfs -s [-d remote_dir]" 5 | } 6 | 7 | function nsshfs() { 8 | local remote_dir='/' 9 | local server='' 10 | local OPTIND=1 11 | 12 | while getops "hd:s:" opt; do 13 | case ${opt} in 14 | h ) 15 | __nsshfs_usage 16 | return 0 17 | ;; 18 | d ) 19 | local remote_dir=$OPTARG 20 | ;; 21 | s ) 22 | local server=$OPTARG 23 | ;; 24 | \? ) 25 | echo -e "Invalid options" 26 | __nsshfs_usage 27 | return 1 28 | ;; 29 | esac 30 | done 31 | 32 | if [ -z "$server" ]; then 33 | __nsshfs_usage 34 | return 1 35 | fi 36 | 37 | if [ -d ~/.sshfs ]; then mkdir ~/.sshfs > /dev/null 2 &1; fi 38 | if [ -d ~/.sshfs/"$server" ]; then mkdir ~/.sshfs/"$server" > /dev/null 2>&1; fi 39 | 40 | echo -e "sshfs -o default_permissions $server:$remote_dir $HOME/.sshfs/$server" 41 | echo -e "nvim $HOME/.sshfs/$server" 42 | echo -e "fusemount -zu $HOME/.sshfs/$server" 43 | echo -e "rm -rf $HOME/.sshfs/$server" 44 | } 45 | -------------------------------------------------------------------------------- /bash/running: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | set -u 4 | 5 | process_list="$(ps -eo 'pid command')" 6 | if [[ $# != 0 ]]; then 7 | process_list="$(echo "$process_list" | grep -Fiw "$@")" 8 | fi 9 | 10 | echo "$process_list" | 11 | grep -Fv "${BASH_SOURCE[0]}" | 12 | grep -Fv grep | 13 | GREP_COLOR='00;35' grep -E --colour=auto '^\s*[[:digit:]]+' 14 | 15 | -------------------------------------------------------------------------------- /bash/sessions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Usage Function 4 | function usage { 5 | echo "Usage: $(basename "$0") -s servicename-tier [-a app-node-count]" 2>"&1" 6 | echo 'Display active Wildfly application node session counts' 7 | echo ' -s: REQUIRED The service name, including its tier.' 8 | echo ' -a: OPTIONAL The number of app nodes if not 4.' 9 | exit 1 10 | } 11 | 12 | if [[ ${#} -lt 1 ]]; then 13 | usage 14 | elif [[ ${#} -lt 2 ]]; then 15 | service=$1 16 | inst=4 17 | elif [[ ${#} -lt 3 ]]; then 18 | service=$1 19 | inst=$2 20 | fi 21 | 22 | echo -e "\n\tWildfly Session Counts\n" 23 | 24 | fmt=" %-30s\t\t\t%s\t%s \n" 25 | printf "$fmt" "NODE NAME" "BLUE" "GREEN" 26 | 27 | for (( x=1; x<="$inst"; x++ )) 28 | do 29 | printf "$fmt" $(echo ome-$service-app-0$x) \ 30 | $(curl -s http://ome-$service-app-0$x.prod.aws.ksu.edu/mod_cluster-manager/ | egrep "id:.*:blue_cluster" | wc -l)" \ 31 | $(curl -s http://ome-$service-app-0$x.prod.aws.ksu.edu/mod_cluster-manager/ | egrep "id:.*:green_cluster" | wc -l)" 32 | done 33 | 34 | -------------------------------------------------------------------------------- /bash/shrug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | LC_CTYPE=UTF-8 6 | echo "¯\_(ツ)_/¯" | pbcopy 7 | -------------------------------------------------------------------------------- /bash/sslchain.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # from https://sharats.me/posts/shell-script-best-practices/ 4 | 5 | # So that when a command fails, bash exits instead of continuing with the rest of the script. 6 | set -o errexit 7 | 8 | # This will make the script fail, when accessing an unset variable. Saves from horrible unintended consequences, with typos in variable names. 9 | # When you want to access a variable that may or may not have been set, use "${VARNAME-}" instead of "$VARNAME", and you’re good. 10 | set -o nounset 11 | 12 | # This will ensure that a pipeline command is treated as failed, even if one command in the pipeline fails. 13 | set -o pipefail 14 | 15 | # People can now enable debug mode, by running your script as TRACE=1 ./script.sh instead of ./script.sh. 16 | if [[ "${TRACE-0}" == "1" ]]; then 17 | set -o trace 18 | fi 19 | 20 | # Check if the first arg is -h or --help or help or just h or even -help, and in all these cases, print help text and exit. 21 | if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then 22 | echo 'Usage: ./slchain.sh hostname 23 | 24 | sslchain.sh parses the entire SSL chain for the given domain, and displays the dates each part is valid. 25 | 26 | ' 27 | exit 28 | fi 29 | 30 | if [[ $# -ne 2 ]]; then 31 | echo "Usage: $0 " 32 | exit 2 33 | fi 34 | 35 | # If appropriate, change to the script’s directory close to the start of the script. 36 | cd "$(dirname "$0")" 37 | 38 | main() { 39 | echo "do awesome stuff" 40 | 41 | FULLCHAIN=$(openssl s_client -connect "$1":"$2" -showcerts 2>/dev/null /dev/null 2>&1 | wc -l` 5 | if [ ! -z $testsvn ] ; then 6 | echo "In svn controlled directory" 7 | else 8 | echo "Not in svn controlled directory" 9 | fi 10 | } 11 | 12 | svn_check 13 | -------------------------------------------------------------------------------- /bash/sway-prop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | set -o pipefail 4 | 5 | 6 | # hint: 7 | # sleep 2; sway-prop 8 | 9 | TMP=/tmp/sway-prop-$PID.tmp 10 | 11 | trap "rm $TMP" EXIT 12 | 13 | swaymsg -t get_tree | jq '.. | select(.type?) | select(.focused==true)' > $TMP 14 | 15 | if [[ -t 1 ]]; then 16 | cat $TMP 17 | else 18 | # I prefer to popup a terminal eg: 19 | #mrxvt -e bash -c "less $TMP" 20 | # ... but sway doesn't have anything like i3-sensible-terminal. 21 | # swaynag is always installed with sway, so: 22 | swaynag -l -m sway-prop < $TMP 23 | fi 24 | -------------------------------------------------------------------------------- /bash/template.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # from https://sharats.me/posts/shell-script-best-practices/ 4 | 5 | # So that when a command fails, bash exits instead of continuing with the rest of the script. 6 | set -o errexit 7 | 8 | # This will make the script fail, when accessing an unset variable. Saves from horrible unintended consequences, with typos in variable names. 9 | # When you want to access a variable that may or may not have been set, use "${VARNAME-}" instead of "$VARNAME", and you’re good. 10 | set -o nounset 11 | 12 | # This will ensure that a pipeline command is treated as failed, even if one command in the pipeline fails. 13 | set -o pipefail 14 | 15 | # People can now enable debug mode, by running your script as TRACE=1 ./script.sh instead of ./script.sh. 16 | if [[ "${TRACE-0}" == "1" ]]; then 17 | set -o trace 18 | fi 19 | 20 | # Check if the first arg is -h or --help or help or just h or even -help, and in all these cases, print help text and exit. 21 | if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then 22 | echo 'Usage: ./template.sh arg-one arg-two 23 | 24 | This is an awesome bsh script to make your life better. 25 | 26 | ' 27 | exit 28 | fi 29 | 30 | # If appropriate, change to the script’s directory close to the start of the script. 31 | cd "$(dirname "$0")" 32 | 33 | main() { 34 | echo "do awesome stuff" 35 | } 36 | 37 | main "$@" 38 | -------------------------------------------------------------------------------- /bash/term: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Open a new Mac OS X terminal window with the command given as an argument 4 | # 5 | # - If there are no arguments, the new terminal window will be opened in the 6 | # current directory, i.e., as if the command would be " cd `pwd`". 7 | # 8 | # - If the first argument is a directory, the new terminal will "cd" into 9 | # that directory before executing the remaining arguments as command. 10 | # 11 | # - If there are arguments and the first on is not a directory, the new 12 | # window will be opened in the current directory and then the arguments 13 | # will be executed as command. 14 | # 15 | # - The optional, leading, "-x" flag will cause the new terminal window to 16 | # be closed immediately after the executed command finishes. 17 | # 18 | # Written by Marc Liyanage 19 | # Copied by Mark Nichols 20 | # 21 | # Version 1.0 22 | # 23 | 24 | if [ "x-x" = x"$1" ]; then 25 | EXIT="; exit"; shift; 26 | fi 27 | 28 | if [[ -d "$1" ]]; then 29 | WD=`cd "$1"; pwd`; shift; 30 | else 31 | WD="'`pwd`'"; 32 | fi 33 | 34 | COMMAND="cd $WD; $@" 35 | echo "$COMMAND $EXIT" 36 | 37 | osascript 2>/dev/null </dev/null 2>&1 5 | -------------------------------------------------------------------------------- /bash/tmux-multistart: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # for use in tmux 3 | # assumes chef repositories set up for chef servers in: 4 | # ~/code/chef/"chefreponame" where chefrepo is a symlink to the repository 5 | # bind-key C command-prompt -p "machine(s)/group: " "run-shell 'tmux-multistart %1'" 6 | 7 | if [ -z "$*" ]; then 8 | read servers 9 | else 10 | servers="$@" 11 | fi 12 | 13 | if [ "${servers[0]}" == "chef" ]; then 14 | cd ~/src/${servers[0]}/${servers[1]} 15 | servers="*${servers[0]}/${servers[1]}:${servers[2]} `knife search -i ${servers[@]:2} | tail +3`" 16 | fi 17 | 18 | fullservers="" 19 | name="`echo $servers | sed -e 's/[. ].*//'`" 20 | 21 | 22 | for serv in $servers; do 23 | if [ -f "$HOME/.dotfiles/machines/$serv" ]; then 24 | fullservers="$fullservers `cat $HOME/.dotfiles/machines/$serv`" 25 | else 26 | if [ "${serv:0:1}" == "*" ]; then 27 | name=${serv:1} 28 | else 29 | fullservers="$fullservers $serv" 30 | fi 31 | fi 32 | done 33 | 34 | tmux new-window -n "$name" 35 | for serv in $fullservers; do 36 | tmux split-window "ssh $serv" 37 | tmux select-layout even-vertical >/dev/null 2>&1 38 | done 39 | tmux kill-pane -t 0 40 | tmux select-layout even-vertical >/dev/null 2>&1 41 | -------------------------------------------------------------------------------- /bash/tmux-sessionizer.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ $# -eq 1 ]]; then 4 | selected=$1 5 | else 6 | selected=$(find ~/code -mindepth 1 -maxdepth 2 -type d | fzf) 7 | fi 8 | 9 | if [[ -z $selected ]]; then 10 | exit 0 11 | fi 12 | 13 | selected_name=$(basename "$selected" | tr . _) 14 | tmux_running=$(pgrep tmux) 15 | if [[ -z $TMUX ]] && [[ -z $tmux_running ]]; then 16 | tmux new-session -s "$selected_name" -c "$selected" 17 | exit 0 18 | fi 19 | 20 | if ! tmux has-session -t "$selected_name" 2> /dev/null; then 21 | tmux new-session -ds "$selected_name" -c "$selected" 22 | fi 23 | 24 | if [[ -z $TMUX ]]; then 25 | tmux attach-session -t "$selected_name" 26 | else 27 | tmux switch-client -t "$selected_name" 28 | fi 29 | -------------------------------------------------------------------------------- /bash/tmuxip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | # UTUNIP=$(ifconfig | grep "inet 10.130" | grep -v broadcast | awk '{print $2}') 6 | UTUNIP=$(ifconfig | grep "inet 100." | awk '{print $2}') 7 | echo " ts: $UTUNIP" 8 | -------------------------------------------------------------------------------- /bash/today: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | # 6 | # today: Create new daily log file from template, or edit existing one, if it 7 | # is already created. If passed an argument, assume it is a bolus of data to be 8 | # appended to the end of the file as is. 9 | # 10 | 11 | # 0 args, create/edit daily log file 12 | # 1 arg eq 'template' - edit template file 13 | # 1 arg ne 'template' - append argument to end of current day log file 14 | 15 | if [[ $# -ne 0 && $# -ne 1 ]]; then 16 | echo "Usage: $0 - to create/edit daily log file" 17 | echo " : $0 template - to edit template file" 18 | exit 2 19 | fi 20 | 21 | # Working Storage Section 22 | # year=$(date '+%Y') 23 | # month=$(date '+%m') 24 | # day=$(date '+%d') 25 | 26 | todaydir="$HOME/Documents/notes" 27 | # todaylog="$todaydir"/"$year"/"$month"/"$day"."md" 28 | todaylog="$todaydir/$(date +%Y)/$(date +%m)/$(date +%d).md" 29 | pattern="$HOME/Documents/notes/day.md" 30 | 31 | day_log() { 32 | mkdir -p "$todaydir/$(date +%Y)/$(date +%m)" 33 | 34 | # Determine if daily log file exists, edit or create as necessary 35 | if [ -f "$todaylog" ] ; then 36 | echo "Day log exists, editing file." 37 | else 38 | echo "Day log does not exist, creating new file." 39 | cp "$pattern" "$todaylog" 40 | fi 41 | 42 | } 43 | 44 | if [[ $# -eq 0 ]]; then 45 | day_log 46 | nvim "$todaylog" 47 | exit 0 48 | fi 49 | 50 | if [[ $1 = "template" ]]; then 51 | echo "$1" 52 | echo " edit the template" 53 | nvim "$pattern" 54 | exit 0 55 | fi 56 | -------------------------------------------------------------------------------- /bash/tsession.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # From https://github.com/ThePrimeagen/.dotfiles/blob/master/bin/.local/bin/tmux-sessionizer 4 | 5 | set -e 6 | set -o pipefail 7 | 8 | # Need fzf installed 9 | if ! command -v fzf &> /dev/null; then 10 | echo "fzf not installed." 11 | exit 1 12 | fi 13 | 14 | if [[ $# -eq 1 ]]; then 15 | selected=$1 16 | else 17 | # selected=$(find ~/work/builds ~/ ~/work ~/personal -mindepth 1 -maxdepth 1 -type d | fzf) 18 | # selected=$(find ~/code ~/ ~/src -mindepth 1 -maxdepth 1 -type d | fzf) 19 | # Trailing slashes behave differently on Linux and MaxOS (BSD-based). I.e., 20 | # `~/` will produce `//` in the resulting paths on MacOS. On Linux `~/` works 21 | # without a hitch 22 | selected=$(find ~/code ~ -mindepth 1 -maxdepth 1 -type d | fzf) 23 | fi 24 | 25 | if [[ -z "$selected" ]]; then 26 | exit 0 27 | fi 28 | 29 | selected_name=$(basename "$selected" | tr . _) 30 | tmux_running=$(pgrep tmux) || true 31 | 32 | if [[ -z $TMUX ]] && [[ -z "$tmux_running" ]]; then 33 | tmux new-session -s "$selected_name" -c "$selected" 34 | exit 0 35 | fi 36 | 37 | if ! tmux has-session -t "$selected_name" 2> /dev/null; then 38 | tmux new-session -ds "$selected_name" -c "$selected" 39 | fi 40 | 41 | if [[ -z $TMUX ]]; then 42 | tmux attach-session -t "$selected_name" 43 | else 44 | tmux switch-client -t "$selected_name" 45 | fi 46 | -------------------------------------------------------------------------------- /bash/um.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | # um.sh 7 | # Create X-Windows session for Universal Messaging client 8 | # 9 | 10 | echo "xauth extract /tmp/xauth.$$ `hostname`/unix:${DISPLAY##*:}" 11 | xauth extract /tmp/xauth.$$ `hostname`/unix:${DISPLAY##*:} 12 | 13 | echo "export XAUTHORITY=/tmp/xauth.$$" 14 | export XAUTHORITY=/tmp/xauth.$$ 15 | 16 | echo "chmod a+r /tmp/xauth.$$" 17 | chmod a+r /tmp/xauth.$$ 18 | 19 | echo "cd /opt/softwareag/UniversalMessaging/java/umserver/bin" 20 | cd /opt/softwareag/UniversalMessaging/java/umserver/bin 21 | 22 | echo "sudo -u webmeth ./nenterprisemgr" 23 | sudo -u webmeth ./nenterprisemgr 24 | 25 | -------------------------------------------------------------------------------- /bash/validAlphaNum: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # validAlphaNum -- Ensures that input consists only of alphabetical 4 | # and numeric characters 5 | 6 | validAlphaNum() 7 | { 8 | # Validate arg: returns 0 if all upper+lower+digits; 1 otherwise 9 | 10 | # Remove all unacceptable characters. 11 | validchars="$(echo $1 | sed -e 's/[^[:alnum:]]//g')" 12 | 13 | if [ "$validchars" = "$1" ] ; then 14 | return 0 15 | else 16 | return 1 17 | fi 18 | } 19 | 20 | # Begin main script -- Delete or comment out everything below this line if 21 | # you want to include this in other scripts. 22 | # ============== 23 | # /bin/echo -n "Enter input: " 24 | # read input 25 | # 26 | # # Input validation 27 | # if ! validAlphaNum "$input" ; then 28 | # echo "Please enter only letters and numbers." >&2 29 | # exit 1 30 | # else 31 | # echo "Input is valid." 32 | # fi 33 | # 34 | # exit 0 35 | -------------------------------------------------------------------------------- /bash/validint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # validint -- Validates integer input, allowing negative integers too 4 | 5 | validint() 6 | { 7 | # Valdite first field and test that value against min value $2 and/or 8 | # max value $3 if they are supplied. If the value isn't within range 9 | # or it's not composed of just digits, fail. 10 | 11 | number="$1" 12 | min="$2" 13 | max="$3" 14 | 15 | if [ -z $number ] ; then 16 | echo "You didn't enter anything. Please enter a number." >&2 17 | return 1 18 | fi 19 | 20 | # Is the first character a '-' sign? 21 | if [ "${number%${number#?}}" = "-" ] ; then 22 | testvalue="${number#?}" # Grab all bu the first character to test. 23 | else 24 | testvalue="$number" 25 | fi 26 | 27 | # Create a version of the number that has no digits for testing. 28 | nodigits="$(echo $testvalue | sed 's/[[:digit:]]//g')" 29 | 30 | # Check for nondigit characters 31 | if [ ! -z $nodigits ] ; then 32 | echo "Invlaid number format! Only digits, no commas, spaces, etc." >&2 33 | return 1 34 | fi 35 | 36 | if [ ! -z $min ] ; then 37 | # Is the input less than the minimum value? 38 | if [ "$number" -lt "$min" ] ; then 39 | echo "Your value is too small: smallest acceptable value is $min." >&2 40 | return 1 41 | fi 42 | fi 43 | 44 | if [ ! -z $max ] ; then 45 | # Is the input greater than the maximum value? 46 | if [ "$number" -gt "$max" ] ; then 47 | echo "Your value is too large: largest acceptable value is $max." >&2 48 | return 1 49 | fi 50 | fi 51 | 52 | return 0 53 | } 54 | 55 | # Used for testing only 56 | # if validint "$1" "$2" "$3" ; then 57 | # echo "Input is a valid integer within your constraints." 58 | # fi 59 | -------------------------------------------------------------------------------- /bash/wifisignal.sh: -------------------------------------------------------------------------------- 1 | while x=1; do /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep CtlRSSI; sleep 0.5; done 2 | -------------------------------------------------------------------------------- /bash/zfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | starttime=$(date +%s) 6 | 7 | 8 | 9 | ls -algR /homes/mhn/code > /homes/mhn/tmp2 10 | grep -R campus /homes/mhn/code > /homes/mhn/tmp3 11 | endtime=$(date +%s) 12 | 13 | 14 | 15 | elapsedtime=$(( endtime - starttime)) 16 | echo $elapsedtime 17 | -------------------------------------------------------------------------------- /deprecated/berksconfig: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | if [ -z "$1" ] 6 | then 7 | echo "Usage: $0 [aws-config.json | est-config.json | ome-config.json]" 8 | exit 1 9 | fi 10 | 11 | ln -sf "~/.berkshelf/${1}" ~/.berkshelf/config.json 12 | -------------------------------------------------------------------------------- /deprecated/catwhich: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | set -o pipefail 4 | 5 | # catwhich 6 | # cat a file in your path 7 | 8 | file=$1 9 | 10 | cat $(which "$file") 11 | -------------------------------------------------------------------------------- /deprecated/cloneall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o pipefail 4 | 5 | # Script to get all repositories under a user from bitbucket 6 | # Usage: cloneall.sh [username] [teamname] 7 | 8 | #curl -u ${1} https://api.bitbucket.org/1.0/users/${2} > repoinfo 9 | curl -u "${1}" https://api.bitbucket.org/1.0/users/"${1}" > repoinfo 10 | for repo_name in $(grep \"name\" repoinfo | cut -f4 -d\") 11 | do 12 | git clone ssh://git@bitbucket.org:"${2}"/"$repo_name" 13 | done 14 | -------------------------------------------------------------------------------- /deprecated/colors: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo -e "\\\\e[0mCOLOR_NC (No color)" 3 | echo -e "\\\\e[1;37mCOLOR_WHITE\\\\t\\\\e[0;30mCOLOR_BLACK" 4 | echo -e "\\\\e[0;34mCOLOR_BLUE\\\\t\\\\e[1;34mCOLOR_LIGHT_BLUE" 5 | echo -e "\\\\e[0;32mCOLOR_GREEN\\\\t\\\\e[1;32mCOLOR_LIGHT_GREEN" 6 | echo -e "\\\\e[0;36mCOLOR_CYAN\\\\t\\\\e[1;36mCOLOR_LIGHT_CYAN" 7 | echo -e "\\\\e[0;31mCOLOR_RED\\\\t\\\\e[1;31mCOLOR_LIGHT_RED" 8 | echo -e "\\\\e[0;35mCOLOR_PURPLE\\\\t\\\\e[1;35mCOLOR_LIGHT_PURPLE" 9 | echo -e "\\\\e[0;33mCOLOR_YELLOW\\\\t\\\\e[1;33mCOLOR_LIGHT_YELLOW" 10 | echo -e "\\\\e[1;30mCOLOR_GRAY\\\\t\\\\e[0;37mCOLOR_LIGHT_GRAY" -------------------------------------------------------------------------------- /deprecated/cp_p: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #http://chris-lamb.co.uk/2008/01/24/can-you-get-cp-to-give-a-progress-bar-like-wget/ 3 | cp_p() 4 | { 5 | strace -q -ewrite cp -- "${1}" "${2}" 2>&1 \ 6 | | awk '{ 7 | count += $NF 8 | if (count % 10 == 0) { 9 | percent = count / total_size * 100 10 | printf "%3d%% [", percent 11 | for (i=0;i<=percent;i++) 12 | printf "=" 13 | printf ">" 14 | for (i=percent;i<100;i++) 15 | printf " " 16 | printf "]\r" 17 | } 18 | } 19 | END { print "" }' total_size=$(stat -c '%s' "${1}") count=0 20 | } -------------------------------------------------------------------------------- /deprecated/extractgst.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | workdir=${HOME}/code/shell-theme 4 | if [ ! -d ${workdir}/theme ]; then 5 | mkdir -p ${workdir}/theme 6 | fi 7 | gst=/usr/share/gnome-shell/gnome-shell-theme.gresource 8 | 9 | for r in `gresource list $gst`; do 10 | gresource extract $gst $r > $workdir/${r#\/org\/gnome\/shell/} 11 | done 12 | -------------------------------------------------------------------------------- /deprecated/loc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # function to count SLOC and then format for the Wiki 3 | if [ -z $3 ] 4 | then 5 | echo "Usage: loc " 6 | exit 1 7 | fi 8 | # tempfile=`basename $0` 9 | # TMPFILE=`/usr/bin/mktemp -q /tmp/${tempfile}.XXXXXX` 10 | # if [ $? -ne 0 ]; then 11 | # echo "$0: Can't create temp file, exiting..." 12 | # exit 1 13 | # fi 14 | /usr/local/sloccount/bin/sloccount --wide --multiproject $1 > $2 15 | /Users/mhn/bin/sloc2conf.py $2 > $3 16 | 17 | # rm ${TMPFILE} 18 | -------------------------------------------------------------------------------- /deprecated/login-hook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$(ps ax | grep tunnel-start.sh | grep -vc grep)" -lt 1 ]; then 4 | sudo -u mhn /Users/mhn/bin/tunnel-start.sh & 5 | fi 6 | -------------------------------------------------------------------------------- /deprecated/normdate: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # normdate -- Normalize month field in date specification to three letters, 4 | # first letter capitalized. A helper function for the valid-date script. 5 | # Exits with 0 if no error. 6 | 7 | monthNumToName() 8 | { 9 | # echo "Input month $1 day $2 year $3" 10 | # Sets the 'month' variable to the appropriate value. 11 | case $1 in 12 | 1 ) month="Jan" ;; 13 | 2 ) month="Feb" ;; 14 | 3 ) month="Mar" ;; 15 | 4 ) month="Apr" ;; 16 | 5 ) month="May" ;; 17 | 6 ) month="Jun" ;; 18 | 7 ) month="Jul" ;; 19 | 8 ) month="Aug" ;; 20 | 9 ) month="Sep" ;; 21 | 10) month="Oct" ;; 22 | 11) month="Nov" ;; 23 | 12) month="Dec" ;; 24 | * ) echo "$0: Unknown month value $1" >&2 25 | exit 1 26 | esac 27 | # echo $month $2 $3 28 | return 0 29 | } 30 | 31 | # Begin Main script -- Delete or comment out everything below this line if 32 | # you want to include this in other scripts. 33 | # ============ 34 | # Input validation 35 | # if [ $# -eq 1 ] ; then # To compensate for / or - formats 36 | # set - - $(echo $1 | sed 's/[\/\-]/ /g') 37 | # fi 38 | # if [ $# -ne 3 ] ; then 39 | # echo "Usage: $0 month day year" >&2 40 | # echo "Formats are August 3 192 and 8 3 1962" >&2 41 | # exit 1 42 | # fi 43 | # if [ $3 -le 99 ] ; then 44 | # echo "$0: expected 4-digit year value." >&2 45 | # exit 1 46 | # fi 47 | # 48 | # # Is the month input format a number? 49 | # if [ -z $(echo $1|sed 's/[[:digit:]]//g') ] ; then 50 | # monthNumToName $1 51 | # else 52 | # # Normalize to first 3 letters, first upper- and then lowercase. 53 | # month="$(echo $1 | cut -c1 | tr '[:lower:]' '[:upper:]')" 54 | # month="$month$(echo $1|cut -c2-3 | tr '[:upper:]' '[:lower:]')" 55 | # fi 56 | # 57 | # echo $month $2 $3 58 | # 59 | # exit 0 60 | -------------------------------------------------------------------------------- /deprecated/pair: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | command=$(basename $0) 4 | 5 | # Make sure dependencies are installed 6 | if [ ! $(command -v gh-auth) ]; then 7 | gem install github-auth 8 | fi 9 | if [ ! $(command -v tmux) ]; then 10 | echo "This script depends on tmux. Try: brew install tmux" 11 | exit 1 12 | fi 13 | if [ ! $(command -v ng) ]; then 14 | echo "This script depends on https://github.com/iamvery/dotfiles/blob/master/bin/ng" 15 | exit 1 16 | fi 17 | 18 | help(){ 19 | echo "Usage: $command [options]\n" 20 | echo "Subcommands:" 21 | echo " add Add a github user" 22 | echo " rm Remove a github user" 23 | echo " ls List github users" 24 | echo " up Open shared tmux session" 25 | echo " ssh Start a reverse tunnel for pair sharing" 26 | echo " See: https://ngrok.com" 27 | echo "" 28 | echo "** Full Disclosure: This script uses sudo **" 29 | echo "" 30 | } 31 | 32 | add(){ 33 | gh-auth add --users $@ --command="$(which tmux) attach -t pairing" 34 | } 35 | 36 | rm(){ 37 | gh-auth remove --users $@ 38 | } 39 | 40 | ls(){ 41 | gh-auth list 42 | } 43 | 44 | up(){ 45 | # Add any users, if specified 46 | if [[ ! -z $@ ]]; then 47 | add $@ 48 | fi 49 | 50 | tmux new-session -d -s pairing "ng connect" 51 | tmux split-window 52 | sleep 0.5 # some delay so tunnel has time to get up 53 | tmux send-keys "pair ssh" C-m 54 | tmux attach 55 | } 56 | 57 | ssh(){ 58 | clipboard_helper="reattach-to-user-namespace" 59 | ssh_command=$(ng ssh) 60 | echo $ssh_command 61 | 62 | if [ $(command -v $clipboard_helper) ]; then 63 | echo $ssh_command | $clipboard_helper pbcopy 64 | else 65 | echo "You must have $clipboard_helper installed to copy ssh command automatically. Try: brew install $clipboard_command" 66 | fi 67 | } 68 | 69 | subcommand=$1 70 | case $subcommand in 71 | '' | '-h' | '--help') 72 | help ;; 73 | *) 74 | shift 75 | ${subcommand} $@ 76 | ;; 77 | esac 78 | -------------------------------------------------------------------------------- /deprecated/pdbsetup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # pdbsetup - copy property files from their location in newly checked out workspace 4 | # to their proper location in jBoss server instance. 5 | 6 | if [ -z "$1" ] ; then 7 | echo "Usage: pdbsetup BaseDirectory" >$2 ; exit 1 8 | fi 9 | 10 | exit 0 -------------------------------------------------------------------------------- /deprecated/settings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## Create new eclipse workspace and copy the settings from the old workspace 4 | ## Tomas Kramar, kramar.tomas@gmail.com, 2008 5 | ## 6 | ## This code is free, you may do whatever you want with it, 7 | ## just keep my name somewhere in the script. 8 | 9 | function die { 10 | echo $1 11 | exit 1 12 | } 13 | 14 | if [ $(whoami) = "root" ]; then 15 | echo "Don't do this as root" 16 | exit 1 17 | fi 18 | 19 | if [ "$#" = "1" -a "$1" = "-i" ]; then 20 | echo -n "Path to old workspace: " 21 | read OLD_WORKSPACE 22 | echo -n "Path to new workspace: " 23 | read NEW_WORKSPACE 24 | fi 25 | 26 | if [ "$#" = "2" ]; then 27 | OLD_WORKSPACE=$1; 28 | NEW_WORKSPACE=$2; 29 | fi 30 | 31 | if [ "$#" = "0" -o "$#" -gt "2" ]; then 32 | echo usage: $0 [-i] old-workspace new-workspace 33 | exit 1 34 | fi 35 | 36 | if [[ ! ( ( -d "$OLD_WORKSPACE" ) && ( -r "$OLD_WORKSPACE" ) ) ]]; then 37 | echo $OLD_WORKSPACE is not a readable directory 38 | exit 1 39 | fi 40 | 41 | WORKSPACE_DIR=`dirname $NEW_WORKSPACE` 42 | 43 | if [[ ! ( ( -d "$WORKSPACE_DIR" ) && ( -w "$WORKSPACE_DIR" ) ) ]]; then 44 | echo $WORKSPACE_DIR is not a writable directory 45 | exit 1 46 | fi 47 | 48 | mkdir -p $NEW_WORKSPACE || die Could not create directory $NEW_WORKSPACE 49 | 50 | mkdir -p $NEW_WORKSPACE/.metadata/.plugins/org.eclipse.core.runtime/ || die Could not create eclipse settings directory 51 | 52 | cp -R $OLD_WORKSPACE/.metadata/.plugins/org.eclipse.core.runtime/.settings/ $NEW_WORKSPACE/.metadata/.plugins/org.eclipse.core.runtime/ || die Could not copy old settings 53 | 54 | echo New workspace created. Now start your Eclipse and point it to the $NEW_WORKSPACE workspace 55 | -------------------------------------------------------------------------------- /deprecated/tr.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # This script opens the Twitterrific application. 4 | # 5 | # who when what 6 | # mhn 7.2.2009 initial version of script 7 | # 8 | # 9 | handle = open /Applications/Twitterrific.app -------------------------------------------------------------------------------- /deprecated/tunnel-start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while [ 1 ]; do 4 | ssh -N -L 3689:eeyore.gotdns.org:3689 mark@eeyore.gotdns.org 5 | sleep 5 6 | done -------------------------------------------------------------------------------- /deprecated/tweet: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This script posts a tweet to Twitter using the text given as input for the tweet text. 4 | # 5 | # who when what 6 | # mhn 6.24.2009 initial version of tweet 7 | 8 | # 9 | # 10 | if [ "$1" = "-h" ]; then 11 | echo "Usage $0 [-h] tweet \n Use -h for help." >&2; exit 1 12 | fi 13 | 14 | curl --basic --user "zanshin:Nji90okm" --data-ascii "status=$1" "http://twitter.com/statuses/update.json" 15 | 16 | echo "Tweeted" -------------------------------------------------------------------------------- /perl/loggy.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | %hashdata = (); 4 | 5 | while(<>) { 6 | chomp(); 7 | @arr = split(/\t/); 8 | ($date,$time,$fn,$ip) = @arr; 9 | # print "$date\t$time\t$fn\t$ip\n"; 10 | if(!defined($hashdata{$fn}{$date}{$ip})) { 11 | $hashdata{$fn}{$date}{$ip}{"start"} = $time; 12 | $hashdata{$fn}{$date}{$ip}{"end"} = $time; 13 | } else { 14 | if($hashdata{$fn}{$date}{$ip}{"start"} gt $time) { 15 | $hashdata{$fn}{$date}{$ip}{"start"} = $time; 16 | } 17 | if($hashdata{$fn}{$date}{$ip}{"end"} lt $time) { 18 | $hashdata{$fn}{$date}{$ip}{"end"} = $time; 19 | } 20 | } 21 | } 22 | 23 | # use Data::Dumper; 24 | # Dumper(%hashdata); 25 | 26 | foreach my $file (keys(%hashdata)) { 27 | foreach my $date (keys(%{$hashdata{$file}})) { 28 | foreach my $ip (keys(%{$hashdata{$file}{$date}})) { 29 | print "$file\t$date\t$ip\t".$hashdata{$file}{$date}{$ip}{"start"}."\t".$hashdata{$file}{$date}{$ip}{"end"}."\n"; 30 | } 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /perl/weathergeek.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | # grab all the lines and put in an array 4 | @w = <>; 5 | 6 | # keep only certain lines for the current conditions 7 | @t = grep /^ +(Temperature|Wind|Humidity|Conditions|Updated|Observed|Pressure)/, @w; 8 | 9 | # erasae the leading spaces and parenthedtical values 10 | for (@t){s/^ +//;s/\(\)//g}; 11 | 12 | # we want the temperature line to print on the bottom to make it 13 | # easy to see on the desktop. The temperature is always on the 14 | # second line, so exchange it with the last line. 15 | # ($t[$#t], $t[1]) = ($t[1], $t[$#t]); 16 | 17 | # sometimes there is a windchill line, sometimes not. 18 | # add a blank line to the front of the array if there isn't 19 | unshift @t, "\n" if $#t == 2; 20 | 21 | # print the lines of interest in the order I want 22 | print join "", @t; -------------------------------------------------------------------------------- /python/ex_machina.py: -------------------------------------------------------------------------------- 1 | #BlueBook code decryption 2 | import sys 3 | def sieve(n): 4 | x = [1] * n 5 | x[1] = 0 6 | for i in range(2,n/2): 7 | j = 2 * i 8 | while j < n: 9 | x[j] = 0 10 | j = j + i 11 | return x 12 | 13 | def prime(n,x): 14 | i = 1 15 | j = 1 16 | while j <= n: 17 | if x[i] == 1: 18 | j = j +1 19 | i = i + 1 20 | return i - 1 21 | x=sieve(10000) 22 | code = [1206,301,384,5] 23 | key =[1,1,2,2,] 24 | 25 | sys.stdout.write("".join(chr(i) for i in [73,83,66,78,32,61,32])) 26 | for i in range (0,4): 27 | sys.stdout.write(str(prime(code[i],x)-key[i])) 28 | 29 | print 30 | -------------------------------------------------------------------------------- /python/get_itunes_movie_art.py: -------------------------------------------------------------------------------- 1 | import urllib, urllib2 2 | import json 3 | import webbrowser 4 | 5 | SEARCH_URL = "http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/wa/wsSearch?entity=movie&term=" 6 | 7 | def get_art(): 8 | term = raw_input("Enter movie title: ") 9 | term = urllib.quote_plus(term) 10 | 11 | response = urllib2.urlopen("%s%s" % (SEARCH_URL, term)) 12 | results = json.load(response) 13 | 14 | if results['resultCount'] > 0: 15 | for index, result in enumerate(results['results']): 16 | print "%s. %s" % (index+1, result['trackName']) 17 | which = raw_input("Enter the number of the movie you want to use: ") 18 | try: 19 | which = int(which) - 1 20 | except: 21 | which = None 22 | if which != None: 23 | url = results['results'][which]['artworkUrl100'].replace("100x100-75.", "") 24 | webbrowser.open(url) 25 | else: 26 | print "No results found" 27 | 28 | get_art() 29 | 30 | if __name__ == "__main__": 31 | get_art() -------------------------------------------------------------------------------- /python/getip.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # from http://www.cs.cmu.edu/~benhdj/Mac/unix.html#getIP 4 | # added colorized output from http://www.siafoo.net/snippet/88 5 | 6 | import urllib, re, sys, os 7 | 8 | # if this changes we need to revise the code to get the external IP 9 | ip_telling_url = 'http://www.dyndns.org/cgi-bin/check_ip.cgi' 10 | 11 | if len(sys.argv) == 1: 12 | # get the external IP 13 | mo = re.search(r'\d+\.\d+\.\d+\.\d+', urllib.urlopen(ip_telling_url).read()) 14 | if mo: 15 | print '\033[1;36mext\033[1;m ' + mo.group() 16 | else: 17 | print '\033[1;36mext\033[1;m not active' 18 | else: 19 | # get the internal IP of an interface 20 | targetInt = sys.argv[1] 21 | output = os.popen('ipconfig getifaddr %s 2>&1' % targetInt).read().strip() 22 | if re.match(r'\d+\.\d+\.\d+\.\d+', output): 23 | print '\033[1;36m' + targetInt + '\033[1;m' + ' ' + output 24 | else: 25 | print '\033[1;36m%s\033[1;m not active' % targetInt -------------------------------------------------------------------------------- /python/passgen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import random 3 | f = open('/usr/share/dict/words') 4 | words = map(lambda x: x.strip(), f.readlines()) 5 | password = '-'.join(random.choice(words) for i in range(2)).capitalize() 6 | password += str(random.randint(1, 9999)) 7 | print (password) 8 | -------------------------------------------------------------------------------- /python/uploadr.history.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanshin/bin/251da0aafdd46479e789ab2fe8762ac767ab1662/python/uploadr.history.db -------------------------------------------------------------------------------- /python/words.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import os 3 | import re 4 | import sys 5 | import getopt 6 | 7 | def main(argv): 8 | 9 | # path = '/path/to/jekyll/posts/' 10 | #path = '/Users/mark/Projects/octopress/solfege/source/_posts/' 11 | dirpath = '/Users/mark/code/' 12 | # site = 'zanshin' 13 | site = 'blog' 14 | posts = '/_posts/' 15 | 16 | try: 17 | opts, args = getopt.getopt(sys.argv,"hs:",["sitename="]) 18 | except getopt.GetoptError: 19 | print "words.py -s " 20 | sys.exit(2) 21 | 22 | for opt, arg in opts: 23 | if opt in ('-h'): 24 | print "words.py -s " 25 | sys.exit() 26 | elif opt in ("-s", "--sitename"): 27 | site = arg 28 | 29 | wordCount = 0 30 | path = dirpath+site+posts 31 | 32 | # Regex to match YAML front matter and everything after it 33 | regex = re.compile("(?s)(---.*---)(.*)") 34 | 35 | # Iterate through all posts 36 | for post in os.listdir(path): 37 | f = open(path+post, "r") 38 | result = re.match(regex, f.read()) 39 | # Count words in everything after YAML front matter 40 | wordCount += len(result.group(2).split()) 41 | print "{:,}".format(wordCount) + " words!" 42 | 43 | if __name__ == "__main__": 44 | main(sys.argv[1:]) 45 | -------------------------------------------------------------------------------- /random/mate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanshin/bin/251da0aafdd46479e789ab2fe8762ac767ab1662/random/mate -------------------------------------------------------------------------------- /random/ngrok: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanshin/bin/251da0aafdd46479e789ab2fe8762ac767ab1662/random/ngrok -------------------------------------------------------------------------------- /rubygems/htmldiff: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby -w 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'diff-lcs' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('diff-lcs', 'htmldiff', version) 26 | else 27 | gem "diff-lcs", version 28 | load Gem.bin_path("diff-lcs", "htmldiff", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/kramdown: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'kramdown' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('kramdown', 'kramdown', version) 26 | else 27 | gem "kramdown", version 28 | load Gem.bin_path("kramdown", "kramdown", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/ldiff: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby -w 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'diff-lcs' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('diff-lcs', 'ldiff', version) 26 | else 27 | gem "diff-lcs", version 28 | load Gem.bin_path("diff-lcs", "ldiff", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/nokogiri: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'nokogiri' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('nokogiri', 'nokogiri', version) 26 | else 27 | gem "nokogiri", version 28 | load Gem.bin_path("nokogiri", "nokogiri", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/reverse_markdown: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'reverse_markdown' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('reverse_markdown', 'reverse_markdown', version) 26 | else 27 | gem "reverse_markdown", version 28 | load Gem.bin_path("reverse_markdown", "reverse_markdown", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/rubocop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'rubocop' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('rubocop', 'rubocop', version) 26 | else 27 | gem "rubocop", version 28 | load Gem.bin_path("rubocop", "rubocop", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/ruby-parse: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'parser' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('parser', 'ruby-parse', version) 26 | else 27 | gem "parser", version 28 | load Gem.bin_path("parser", "ruby-parse", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/ruby-rewrite: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'parser' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('parser', 'ruby-rewrite', version) 26 | else 27 | gem "parser", version 28 | load Gem.bin_path("parser", "ruby-rewrite", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/solargraph: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'solargraph' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('solargraph', 'solargraph', version) 26 | else 27 | gem "solargraph", version 28 | load Gem.bin_path("solargraph", "solargraph", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/thor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'thor' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('thor', 'thor', version) 26 | else 27 | gem "thor", version 28 | load Gem.bin_path("thor", "thor", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/tilt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'tilt' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('tilt', 'tilt', version) 26 | else 27 | gem "tilt", version 28 | load Gem.bin_path("tilt", "tilt", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/yard: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'yard' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('yard', 'yard', version) 26 | else 27 | gem "yard", version 28 | load Gem.bin_path("yard", "yard", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/yardoc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'yard' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('yard', 'yardoc', version) 26 | else 27 | gem "yard", version 28 | load Gem.bin_path("yard", "yardoc", version) 29 | end 30 | -------------------------------------------------------------------------------- /rubygems/yri: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # This file was generated by RubyGems. 4 | # 5 | # The application 'yard' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'rubygems' 10 | 11 | Gem.use_gemdeps 12 | 13 | version = ">= 0.a" 14 | 15 | str = ARGV.first 16 | if str 17 | str = str.b[/\A_(.*)_\z/, 1] 18 | if str and Gem::Version.correct?(str) 19 | version = str 20 | ARGV.shift 21 | end 22 | end 23 | 24 | if Gem.respond_to?(:activate_bin_path) 25 | load Gem.activate_bin_path('yard', 'yri', version) 26 | else 27 | gem "yard", version 28 | load Gem.bin_path("yard", "yri", version) 29 | end 30 | -------------------------------------------------------------------------------- /twitter/followers.csv: -------------------------------------------------------------------------------- 1 | eclawson,emilyapeterson,ART_MikeLyon,BetaTest_Music,Joshtropovich,TonyBurrage,EmilyCello,Emilee345586,imslp,derekstegelman,jim_neff,ImAGuitarGirl,faustman,neophytecellist,SarasShop,ardithcello,riksca,CelloAl,wademwilson,WildPwnguin,RalphBassfeld,improvcellist,naveedprince11,timcorriejr,QuartettoAnthos,nbksk7,Britt0577,AndreaBichsel,donaldsbell,PitaPitMHK,catepolacek,completeandroid,TyReynoldsKS,VisitFairfax,KremllinRussia,MusicForStrings,brianjesse,manhattan24_7,cellostudio,Zappos_Service,TrusharMMA,lownote,cellomike,JerryWindham,DanielDennis,logandk,JosettPKizio,gottagopractice,biblequotes,crystaldoorknob,paulpul,backupify,getwildfire,MHKid,J_Krautkraemer,infocusprojecto,sonyprojector,dellprojector,theaudioj,Fletcher_681,djaijung,ride2disney,joemako,mydailylist,Morrison_819,AlgoMusical777,JeanieHood390,KStateYoungDems,Richart775,BettyRoman214,itunes__9_,iratwo,eHarmonySuccess,WeRetouchPics,norbertacuna,caffey,BrentonLewisqmo,asaleitest,alexchuang,gpennington,kstate_pres,bobweberemp,abhishekhp,ILtider,JavaOneConf,aharrington49,myen,courtenaybird,bluetachikoma,dillandpickle,TweetDr,jeremiahshirk,thecurtain,cholick,worksology,49news,paulapoundstone,onlinecollege,IBMResearch,renaebair,kvetch,jleard,WholeFoods,kylerheckman,BestIndyGuide,ObamaNews,BarackObama,MikeTRose,minarets,panache,elfenbein -------------------------------------------------------------------------------- /twitter/mycrontab: -------------------------------------------------------------------------------- 1 | # minute hour day-of-month month day-of-week what 2 | 3 | # check for Twitter unfollows every 30 minutes 4 | # 30 * * * * /Users/mark/bin/unfollowers.rb 5 | -------------------------------------------------------------------------------- /zsh/electron-version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | # patched versions for CVE-2023-4863: 22.3.24, 24.8.3, 25.8.1, 26.2.1 4 | mdfind "kind:app" 2>/dev/null | sort -u | while read app; 5 | do 6 | filename="$app/Contents/Frameworks/Electron Framework.framework/Electron Framework" 7 | if [[ -f $filename ]]; then 8 | echo "App Name: $(basename ${app})" 9 | 10 | electronVersion=$(strings "$filename" | grep "Chrome/" | grep -i Electron | grep -v '%s' | sort -u | cut -f 3 -d '/') 11 | echo "Electron Version: $electronVersion" 12 | 13 | echo -n "File Name: $filename " 14 | echo -e "\n" 15 | fi 16 | done 17 | -------------------------------------------------------------------------------- /zsh/git-authorship: -------------------------------------------------------------------------------- 1 | git ls-files -z | xargs -0 -n1 -E'\n' -J {} git blame --date short -wCMcp '{}' | perl -pe 's/^.*?\((.*?) +\d{4}-\d{2}-\d{2} +\d+\).*/\1/' | sort | uniq -c | sort -rn -------------------------------------------------------------------------------- /zsh/git-today: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | # git-today 3 | # Written by: Gianni Chiappetta 4 | # Requires: git 1.7.5+, zsh 4.3.11+ 5 | 6 | function get_user { git config user.email } 7 | 8 | # Command normalisation 9 | cmd="go" 10 | user=$(get_user) 11 | since="1 day ago" 12 | 13 | while getopts "hu:s:" option 14 | do 15 | case $option in 16 | h) 17 | cmd="help" 18 | ;; 19 | u) 20 | user=$OPTARG 21 | ;; 22 | s) 23 | since=$OPTARG 24 | ;; 25 | ?) 26 | cmd="help" 27 | ;; 28 | esac 29 | done 30 | 31 | # Help 32 | read -d '' help_text <<"EOS" 33 | Git Today - Show one big diff of the work you have done in the past day. 34 | Written by: Gianni Chiappetta 35 | 36 | Usage: 37 | git today [arguments...] 38 | 39 | Arguments: 40 | -h 41 | Show this help. 42 | 43 | -u 44 | User to find diff for. Default is current user. 45 | 46 | -s 47 | Date to search since. Default is the last day. 48 | 49 | Examples: 50 | git today 51 | 52 | git today -s "14 days ago" 53 | 54 | git today -u some@email.tld 55 | 56 | git today -s "7 days ago" -u person@email.tld 57 | EOS 58 | 59 | # Meat... mmm 60 | if [[ $cmd = 'help' ]]; then 61 | echo $help_text 62 | return 63 | elif [[ $cmd = 'go' ]]; then 64 | eval $'commits=( ${(s.\n.)"$(git log --pretty="%H %ae" --since="$since" | grep $user | grep -oE \'^[a-f0-9]+\')"} )' 65 | 66 | if [ ${#commits} -eq 1 ]; then 67 | if [ -z $commits ]; then 68 | echo "No commits!" 69 | else 70 | git show $commits 71 | fi 72 | else 73 | git diff $commits[-1]..$commits[0] 74 | fi 75 | fi 76 | 77 | # vim: set filetype=zsh : 78 | --------------------------------------------------------------------------------