├── .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/\
10 | />\
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 'Plot Outline:' $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/- / -- /;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 "
CGI Runtime Environment"
12 | echo ""
13 | env || printenv
14 | echo " "
15 | echo "Input stream is:"
16 | echo ""
17 | cat -
18 | echo "(end of input stream) "
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 |
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
13 | Content-type: text/html
14 | To: $to
15 |
16 |
17 |
18 |
21 | THE STRAIGHT DOPE
22 |
23 |
24 | EOF
25 |
26 | lynx -source "$url" | \
27 | sed -n '/ /,$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 ""
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 | #
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 ""
15 | echo "Kevin & Kell"
16 | echo ""
17 | echo ""
18 | echo "Bill Holbrook's Kevin & Kell | "
19 | echo " "
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 |
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 |
37 |
38 |
40 |
41 |
|